teori struktur data full

44
BAHAN AJAR Program studi : Teknik Informatika Kode Mata Kuliah : IKK112111 Mata kuliah : Struktur Data SKS : 3 SKS Semester : 3 Jenis Mata Kuliah : Wajib Kelompok MK : MKK STMIK EL RAHMA YOGYAKARTA Dibuat Oleh Revisi ke Tanggal dibuat Diperiksa oleh Kaprodi TI

Upload: hidayatullah-aldy

Post on 19-Jul-2015

169 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: teori Struktur data full

BAHAN AJAR

Program studi : Teknik Informatika Kode Mata Kuliah : IKK112111 Mata kuliah : Struktur Data SKS : 3 SKS Semester : 3 Jenis Mata Kuliah : Wajib Kelompok MK : MKK

STMIK EL RAHMA YOGYAKARTA

Dibuat Oleh Revisi ke Tanggal dibuat Diperiksa oleh

Kaprodi TI

Page 2: teori Struktur data full

ii

KATA PENGANTAR

Puji syukut saya penjatkan kehadirat Alloh SWT, atas limpahan rahmad dan hidayahya saya

dapat menyelesaikan bahan ajar untuk mata kuliah Struktur Data Program Studi Teknik

Informatika.

Bahan ajar ini berisikan materi-matari tentang konsep struktur data yang meliputi konsep

linkedlist, double linkedlist, stack, queue, sorting dan seaching, tree. Besar harapan saya bahan

ajar ini akan mempermudah mahasiswa untuk mempelajari Struktur Data.

Tidak lupa saya mengucapkan terima kasih yang sebesar-besarnya kepada semua pihak yang

telah berkontribusi sampai selesainya bahan ajar ini. Untuk menyempurnakan bahan ajar ini,

segala masukan dan saran sangat saya harapkan.

Penyusun

Eko Riswanto

Page 3: teori Struktur data full

iii

DAFTAR ISI

Halaman Depan ........................................................................................................................ i

Kata Pengantar ......................................................................................................................... ii

Daftar Isi .................................................................................................................................. iii

Bab 1 Linked List (Senara Berkait) ........................................................................................ 1

Bab 2 Linked List (Lanjutan) .................................................................................................. 6

Bab 3 Double Linked List ........................................................................................................ 8

Bab 4 Stack (Tumpukan) ........................................................................................................ 14

Bab 5 Stack Dengan Pointer ................................................................................................... 25

Bab 6 Pengurutan (Sorting) .................................................................................................... 30

Bab 7 Pencarian (Searching) .................................................................................................. 33

Bab 8. Pohon (Tree) ................................................................................................................ 35

Page 4: teori Struktur data full

1

BAB 1. LINKED LIST (SENARAI BERKAIT)

Pengertian Linked List

Salah satu bentuk struktur data yang berisi kumpulan data yang tersusun secara sekuensial, saling

bersambungan, dinamis adalah senarai berkait (linked list).Suatu senarai berkait (linked list) adalah

suatu simpul (node) yang dikaitkan dengan simpul yang lain dalam suatu urutan tertentu. Suatu

simpul dapat berbentuk suatu struktur atau class. Simpul harus mempunyai satu atau lebih elemen

struktur atau classyang berisi data.

Secara teori, linked list adalah sejumlah node yang dihubungkan secara linier dengan

bantuanpointer. Dikatakansingle linked apabila hanya ada satu pointer yangmenghubungkan setiap

node.singleartinya field pointernya hanya satu buah saja dan satu arah.

Senarai berkait adalah struktur data yang paling dasar. Senarai berkait terdiri atas

sejumlah unsur-unsur dikelompokkan, atau terhubung, bersama-sama di suatu deret yang

spesifik. Senarai berkait bermanfaat di dalam memelihara koleksi-koleksi data, yang serupa

dengan array/larik yang sering digunakan. Bagaimanapun juga, senarai berkait memberikan

keuntungan-keuntungan penting yang melebihi array/larik dalam banyak hal. Secara rinci, senarai

berkait lebih efisien di dalam melaksanakan penyisipan-penyisipan dan penghapusan-penghapusan. Senarai

berkait juga menggunakan alokasi penyimpanan secara dinamis, yang merupakan penyimpanan yang

dialokasikan pada runtime . Karena di dalam banyak aplikasi, ukuran dari data itu tidak diketahui pada

saat kompile, hal ini bisa merupakan suatu atributyang baik juga. Setiapnodeakan berbentuk struct dan

memiliki satu buahfield bertipe structyang sama, yang berfungsi sebagai pointer. Dalam

menghubungkan setiap node, kita dapat menggunakan cara first-create-first-access ataupun first-create-

last-access. Yang berbeda dengan deklarasi struct sebelumnya adalah satu field bernama next, yang

bertipe struct node. Hal ini sekilas dapat membingungkan. Namun, satu hal yang jelas, variabel next ini akan

menghubungkan kita dengan node di sebelah kita, yang juga bertipe struct node.Hal inilah yang

menyebabkan next harus bertipe struct node

Deklarasi node:

struct node

{

char nama[20];

int umur;

float tinggi;

node *next; // Pointer menyambung ke node selanjutnya

};

Gambar sebuah node:

data point datadata point

1. Bagian pertama, disebut medan informasi, berisi informasi yang akan disimpan dan diolah.

2. Bagian kedua, disebut medan penyambung (link field), berisi alamat simpul berikutnya

Pada gambar di atas, pointer awal menunjuk ke simpul pertama dari senerai tersebut.

Medan penyambung (pointer) dari suatu simpul yang tidak menunjuk simpul lain disebut pointer

kosong, yang nilainya dinyatakan sebagai null (null adalah kata baku yang berarti bahwa pointer

Page 5: teori Struktur data full

2

0 atau bilangan negatif). Jadi kita bisa melihat bahwa dengan hanya sebuah pointer Awal saja

maka kita bisa membaca semua informasi yang tersimpan dalam senerai

MENAMBAH SIMPUL DI BELAKANG

Sekarang kita akan mempelajari bagaimana menambah simpul baru ke dalam senerai berantai.

Kita anggap bahwa simpul baru yang akan ditambah selalu menempati posisi setelah posisi yang

terakhir dari senerai berantai yang diketahui. Untuk menjelaskan operasi ini baiklah kita gunakan

deklarasi pointer dan simpul seperti di bawah ini:

struct node

{

char nama[20];

int umur;

float tinggi;

node *next;

};

Menambahkan simpul diakhir list

Misalkan simpul baru yang dibentuk diberi nama temp. Untuk menambahkan simpul baru

perlu kita uji apakah Linked list masih kosong atau tidak. Linked list yang kosong ditandai

dengan awal_ptr bernilai NULL. Jika tidak kosong maka dibaca senarai yang ada mulai dari

posisi awal sampai terakhir misalkan dengan menggunakan pointer temp2. Simpul terakhir

ditandai dengan medan penyambung dari temp2 bernilai NULL.Jika sudah berada pada simpul

terakhir kita tunjukkan medan penyambung temp2 dengan temp.

Program lengkap menambahkan simpul diakhit senarai sebagai berikut:

node *temp, *temp2; // pointer sementara

// Isi data

temp = new node; //menciptakan node baru

cout << "Nama : ";cin >> temp->nama;

cout << "Umur : ";cin >> temp->umur;

cout << "Tinggi : ";cin >> temp->tinggi;

temp->next = NULL;

// Inisialisasi pointer ketika masih kosong

if (awal_ptr == NULL)

{

awal_ptr = temp;

posisi = awal_ptr;

}

else

{

temp2 = awal_ptr;

// list tidak kosong

while (temp2->next != NULL)

{

temp2 = temp2->next;

// pindah ke link berikutnya

}

temp2->next = temp;

}

Page 6: teori Struktur data full

3

Menghapus simpul diakhir list kita gunakan cara sebagai berikut :

Untuk menghapus simpul diakhir perlu kita uji apakah senarai masih kosong atau tidak, jika

kosong tampilkan pesan bahwa list masih kosong. Jika tidak kosong perlu diuji apakah jumlah

simpul dalam senarai hanya satu yang ditandai dengan medan penyambung yang bernilai null.

Jika simpul lebih dari satu maka dibaca semua simpul sampai simpul terakhir yaitu medan

penyambung bernilai null.

node *temp1, *temp2;

if (awal_ptr == NULL)

cout << "List kosong!" << endl;

else

{

temp1 = awal_ptr;

if (temp1->next == NULL)

{

delete temp1;

awal_ptr = NULL;

}

else

{

while (temp1->next != NULL)

{

temp2 = temp1;

temp1 = temp1->next;

}

delete temp1;

temp2->next = NULL;

}

}

Menghapus simpul diawallist

Menghapus simpul diawal dilakukan dengan cara menampung simpul awal pada pointer temp,

kemudian mengarahkan awal_ptr ke simpul selanjutnya. Kemudian simpul yang ditampung

dalam pointer temp dihapus.

node *temp;

temp = awal_ptr;

awal_ptr = awal_ptr->next;

delete temp;

Menampilkan list

Sebelum menampilkan linked list perlu kita uji apakah senarai kosong atau tidak. Jika senarai

kosong kita tampilkan pesan bahwa List kosong. Jika senarai tidak kosong maka kita baca

senarai mulai posisi awal sampai simpul terakhir.

node *temp;

temp = awal_ptr;

cout << endl;

if (temp == NULL)

cout << "List kosong!" << endl;

else

{

while (temp != NULL)

{

// Menampilkan isi

cout << "Nama : " << temp->nama << " ";

Page 7: teori Struktur data full

4

cout << "Umur : " << temp->umur << " ";

cout << "Tinggi : " << temp->tinggi;

if (temp == posisi)

cout << " <– Posisi node";

cout << endl;

temp = temp->next;

}

cout << "Akhir list!" << endl;

}

Program Lengkap:

#include <iostream.h>

struct node

{

char nama[20];

int umur;

float tinggi;

node *next;

};

node *awal_ptr=NULL;

node *posisi;

int pilih;

void tambah_simpul_akhir()

{

node *temp, *temp2; //simpul sementara

//isi data

temp=new node;

cout<<"Nama : ";cin>>temp->nama;

cout<<"Umur : ";cin>>temp->umur;

cout<<"Tinggi : ";cin>>temp->tinggi;

temp->next=NULL;

//inisialisasi pointer ketika kosong

if(awal_ptr==NULL)

{

awal_ptr=temp;

posisi=awal_ptr;

}

else

{

temp2=awal_ptr;

while(temp2->next != NULL)

{

temp2 = temp2->next;

}

temp2->next=temp;

}

}

void tampil_senarai()

{

node *temp;

temp = awal_ptr;

if(temp == NULL)

cout<<"List kosong"<<endl;

else

{

cout<<endl<<endl;

while(temp != NULL)

{

cout<<"Nama : "<<temp->nama<<" ";

cout<<"Umur : "<<temp->umur<<" ";

cout<<"Tinggi : "<<temp->tinggi;

if (temp == posisi)

cout<<" << posisi simpul";

cout<<endl;

temp=temp->next;

Page 8: teori Struktur data full

5

}

cout<<"Akhir list"<<endl;

}

}

void hapus_simpul_akhir()

{

node *temp1, *temp2;

if (awal_ptr == NULL)

cout << "List kosong!" << endl;

else

{

temp1 = awal_ptr;

if (temp1->next == NULL)

{

delete temp1;

awal_ptr = NULL;

}

else

{

while (temp1->next != NULL)

{

temp2 = temp1;

temp1 = temp1->next;

}

delete temp1;

temp2->next = NULL;

}

}

}

void hapus_simpul_awal()

{

node *temp;

temp = awal_ptr;

awal_ptr = awal_ptr->next;

delete temp;

}

void main()

{

awal_ptr=NULL;

do

{

tampil_senarai();

cout<<"Menu Pilihan"<<endl;

cout<<"0. Keluar program"<<endl;

cout<<"1. Tambah simpul akhir"<<endl;

cout<<"2. Hapus simpul akhir"<<endl;

cout<<"3. Hapus simpul awal"<<endl;

cout<<"Pilihan >> ";cin>>pilih;

switch(pilih)

{

case 1: tambah_simpul_akhir();break;

case 2: hapus_simpul_akhir();break;

case 3: hapus_simpul_awal();break;

}

}while(pilih !=0);

}

Page 9: teori Struktur data full

6

BAB 2. LINKED LIST (LANJUTAN)

Menambah Simpul di Depan

Adalah menambahkan simpul baru yang dimasukkan diawal list. Proses penambahan

simpul diawal list diilustrasikan sebagai berikut:

1. List masih kosong maka awal_ptr bernilai NULL (awal_ptr=NULL)

awal_ptr

NULL

2. Masuk simpul baru, misalkan data A

A

awal_ptrbaru

3. Menambakan simpul diawal simpul A, misalkan simpul B

A

awal_ptr

B

baru

Barunext diisi dengan alamat dimana simpul data A berada, kemudian awal_ptr

ditunjukkan ke simpul baru yang diciptakan.

AB

awal_ptrbaru

Program :

if(awal_ptr == NULL)

{

awal_ptr=baru;

awal_ptr->next = NULL;

}

else

{

baru->next = awal_ptr;

awal_ptr = baru;

}

Menambah Simpul di Tengah

Proses penambahan di tengah berarti proses penyisipan data pada posisi tertentu. Oleh

karena itu, posisi penyisipan sangat diperlukan. Ada beberapa kondisi yang harus diperhatikan

ketika ingin melakukan penyisipandata, yaitu kondisi ketika linked list masih kosong, dan ketika

linked list sudah mempunyai data.

Proses penambahan data ketika linked list sudah mempunyai data. Ada 3 kondisi yang

terjadi ketika akan melakukan proses penyisipan pada linked list yang sudah mempunyai data

adalah :

1. Posisi penyisipan di luar dari jangkauan linked list (posisi kurang dari 1 atau melebihi banyak

data yang ada di linked list). Pada proses ini, jika terjadi posisi penyisipan kurang dari 1

maka proses yang dilakukan adalah proses penambahan data di awal, dan jika posisi diluar

(>) dari banyak data maka proses yang dilakukan adalah proses penambahan data di akhir.

2. Posisi penyisipan di dalam jangkauan linked list. Contoh kalau ingin menyisipkan data pada

posisi ke-3 (posisi_sisip=3).

Page 10: teori Struktur data full

7

A B C D

awal_ptr

E

baru

Posisi_sisi = 3

Langkah selanjutnya cari posisi elemen sebelum posisi sisip kemudian simpan dalam

suatu variabel dengan nama bantu.

A B C D

awal_ptr

E

baru

Posisi_sisi = 3bantu

Kemudian sambungkan field next dari Baru ke posisi next dari bantu

A B C D

awal_ptr

E

baru

Posisi_sisi = 3bantu

Kemudian pindahkan field next dari bantu ke posisi data baru.

A B C D

awal_ptr

E

baru

Posisi_sisi = 3bantu

Program: if(awal_ptr != NULL)

{

cout<<"Akan disisip setelah Data Ke ? : "; cin>>posisi_sisip;

bantu=awal_ptr;

baru =new node;

for(int i=1;i<posisi_sisip-1;i++)

{

if(bantu->next != NULL)

bantu=bantu->next;

else

break;

}

cout << "Masukkan Nama : "; cin >> baru->nama;

cout << "Masukkan Umur : "; cin >> baru->umur;

cout << "Masukkan tingggi : "; cin >> baru->tinggi;

baru->next=bantu->next;

bantu->next=baru;

}

Page 11: teori Struktur data full

8

else

{ cout<<"Belum ada data !! silahkan isi data dulu....";

getch();}

}

Menghapus Simpul di Tengah

Menghapus tengah sebuah simpul adalah menghilangkan simpul dari deret linked list.

Misalkan kita akan menghapus simpul pada posisi 3

A B C D

awal_ptr Posisi_sisi = 3

Tempatkan pointer bantu pada posisi sebelum simpul yang akan dihapus

A B C D

awal_ptr Posisi_sisi = 3bantu

Tempatkan pointer hapus sesuai dengan field next pada bantu

A B C D

awal_ptr Posisi_sisi = 3bantu hapus

Sambungkan field next pada bantu dengan field next pada hapus

A B C D

awal_ptr Posisi_sisi = 3bantu hapus

Langkah terakhir delete simpul hapus.

A B D

awal_ptr

Program: if(awal_ptr != NULL)

{

cout<<" Akan dihapus pada data ke : "; cin>>posisi_hapus;

banyakdata=1;

bantu=awal_ptr;

while(bantu->next != NULL)

{

bantu=bantu->next;

banyakdata++;

}

if((posisi_hapus<1)||(posisi_hapus>banyakdata))

{

cout<<"Belum ada data !! masukkan Data dula aja...\n";

}

else

{

bantu=awal_ptr;

poshapus=1;

while(poshapus<(posisi_hapus-1))

{

bantu=bantu->next;

poshapus++;

}

hapus=bantu->next;

bantu->next=hapus->next;

Page 12: teori Struktur data full

9

delete hapus;

}

}

else cout<<"Data Masih kosong, tidak bisa hapus data dari tengah! ";

getch();

}

Program lengkap:

#include <iostream.h>

#include <conio.h>

struct node

{ char nama[20];

int umur;

float tinggi;

node *next;

};

node *awal_ptr = NULL;

node *posisi; //digunakan untuk membaca sepanjang list

int option = 0;

void tambah_awal_list()

{

node *baru;

baru = new node;

cout << "Masukkan Nama : ";

cin >> baru->nama;

cout << "Masukkan Umur : ";

cin >> baru->umur;

cout << "Masukkan tingggi : ";

cin >> baru->tinggi;

baru->next = NULL;

if(awal_ptr == NULL)

{

awal_ptr=baru;

awal_ptr->next = NULL;

}

else

{

baru->next = awal_ptr;

awal_ptr = baru;

}

}

void menambah_node_di_akhir()

{ node *temp, *temp2; // Temporary pointers

// menciptakan node baru

temp = new node;

cout << "Masukkan Nama : ";

cin >> temp->nama;

cout << "Masukkan Umur : ";

cin >> temp->umur;

cout << "Masukkan tingggi : ";

cin >> temp->tinggi;

temp->next = NULL;

// Set up link pada node

if (awal_ptr == NULL)

{ awal_ptr = temp;

posisi = awal_ptr;

}

else

{ temp2 = awal_ptr;

// node tidak NULL – list tidak kosong

while (temp2->next != NULL)

{ temp2 = temp2->next;

Page 13: teori Struktur data full

10

// Memindahkan pada next link dalam rantai

}

temp2->next = temp;

}

}

void display_list()

{ node *temp;

temp = awal_ptr;

cout << endl;

if (temp == NULL)

cout << "List kosong!" << endl;

else

{ while (temp != NULL)

{ // Menampilkan detail data

cout << "nama : " << temp->nama << " ";

cout << "umur : " << temp->umur << " ";

cout << "tinggi : " << temp->tinggi;

if (temp == posisi)

cout << " <<<< posisi node";

cout << endl;

temp = temp->next;

}

cout << "Akhir list!" << endl;

}

}

void hapus_awal_node()

{ node *temp;

temp = awal_ptr;

awal_ptr = awal_ptr->next;

delete temp;

}

void hapus_akhir_node()

{ node *temp1, *temp2;

if (awal_ptr == NULL)

cout << "List kosong!" << endl;

else

{ temp1 = awal_ptr;

if (temp1->next == NULL)

{ delete temp1;

awal_ptr = NULL;

}

else

{ while (temp1->next != NULL)

{ temp2 = temp1;

temp1 = temp1->next;

}

delete temp1;

temp2->next = NULL;

}

}

}

void pindah_posisi_sebelumnya()

{ if (posisi->next == NULL)

cout << "Kamu berada pada akhir list." << endl;

else

posisi = posisi->next;

}

void pindah_posisi_berikutnya()

{ if (posisi == awal_ptr)

cout << "Kamu berada pada awal list" << endl;

else

{ node *previous; // deklarasi pointer

previous = awal_ptr;

while (previous->next != posisi)

Page 14: teori Struktur data full

11

{ previous = previous->next;

}

posisi = previous;

}

}

void tambah_tengah_list()

{

node *baru, *bantu;

int posisi_sisip;

if(awal_ptr != NULL)

{

cout<<"Akan disisip setelah Data Ke ? : "; cin>>posisi_sisip;

bantu=awal_ptr;

baru =new node;

for(int i=1;i<posisi_sisip-1;i++)

{

if(bantu->next != NULL)

bantu=bantu->next;

else

break;

}

cout << "Masukkan Nama : ";

cin >> baru->nama;

cout << "Masukkan Umur : ";

cin >> baru->umur;

cout << "Masukkan tingggi : ";

cin >> baru->tinggi;

baru->next=bantu->next;

bantu->next=baru;

}

else

{ cout<<"Belum ada data !! silahkan isi data dulu....";

getch();}

}

void Hapus_tengah_list()

{

int banyakdata,posisi_hapus,poshapus;

node *hapus, *bantu;

if(awal_ptr != NULL)

{

cout<<" Akan dihapus pada data ke : "; cin>>posisi_hapus;

banyakdata=1;

bantu=awal_ptr;

while(bantu->next != NULL)

{

bantu=bantu->next;

banyakdata++;

}

if((posisi_hapus<1)||(posisi_hapus>banyakdata))

{

cout<<"Belum ada data !! masukkan Data dula aja...\n";

}

else

{

bantu=awal_ptr;

poshapus=1;

while(poshapus<(posisi_hapus-1))

{

bantu=bantu->next;

poshapus++;

}

hapus=bantu->next;

bantu->next=hapus->next;

delete hapus;

}

}

else cout<<"Data Masih kosong, tidak bisa hapus data dari tengah! ";

getch();

}

Page 15: teori Struktur data full

12

int main()

{ awal_ptr = NULL;

do

{

clrscr();

display_list();

cout << endl;

cout << "MENU PILIHAN : " << endl;

cout << "0. Keluar program." << endl;

cout << "1. Tambah awal list." << endl;

cout << "2. Tambah akhir list." << endl;

cout << "3. Tambah tengah list."<< endl;

cout << "4. Hapus awal list." << endl;

cout << "5. Hapus akhir list." << endl;

cout << "6. Hapus tengah list." << endl;

cout << "7. Pindah posisi pointer ke berikutnya." << endl;

cout << "8. Pindah posisi pointer ke sebelumnya." << endl;

cout << endl << " Pilihan >> ";

cin >> option;

switch (option)

{

case 1 : tambah_awal_list();break;

case 2 : menambah_node_di_akhir(); break;

case 3 : tambah_tengah_list();break;

case 4 : hapus_awal_node(); break;

case 5 : hapus_akhir_node(); break;

case 6 : Hapus_tengah_list();break;

case 7 : pindah_posisi_sebelumnya(); break;

case 8 : pindah_posisi_berikutnya();

}

}

while (option != 0);

}

Page 16: teori Struktur data full

13

BAB 3. DOUBLE LINKED LIST

Elemen-elemen dihubungkan dengan dua pointer dalam satu elemen. Struktur ini menyebabkan

list melintas baik ke depan maupun ke belakang. Masing-masing elemen pada double linked list

terdiri dari tiga bagian, disamping data dan pointer next, masing-masing elemen dilengkapi

dengan pointer prev yang menunjuk ke elemen sebelumnya. Double linked list dibentuk dengan

menyusun sejumlah elemen sehingga pointer next menunjuk ke elemen yang mengikutinya dan

pointer prev menunjuk ke elemen yang mendahuluinya. Untuk menunjukkan head dari double

linked list, maka pointer prev dari elemen pertama menunjuk NULL. Untuk menunjukkan tail

dari double linked list tersebut, maka pointer next dari elemen terakhir menunjuk NULL.

Susunan elemen yang dihubungkan dalam bentuk double linked list dapat dilihat pada Gambar di

bawah ini

data nextprev

Gambar 1. Sebuah simpul dengan menggunakan double linked list

Untuk melintas kembali melalui double linked list, kita gunakan pointer prev dari elemen yang

berurutan pada arah tail ke head. Double linked list mempunyai fleksibilitas yang lebih tinggi

daripada single linked list dalam perpindahan pada list. Bentuk ini sangat berguna ketika akan

meletakkan suatu elemen pada list dan dapat memilih dengan lebih bijaksana bagaimana

memindahkannya. Sebagai contoh, salah satu fleksibilitas dari double linked list adalah dalam

hal memindahkan elemen dari pada menggunakan single linked list.

ANULL B C D NULL

Definisi simpul

struct node

{ char nama[20];

int umur;

float tinggi;

node *prev;

node *next;

};

Setelah node dibuat, buat variabel baru yang bertipe pointer dari node yang berguna sebagai

kepala (head) dan ekor (tail) linked list. Head selalu menunjuk pada simpul pertama, sedangkan tail

selalu menunjuk pada simpul terakhir. node *head=NULL, *tail=NULL;

Operasi pada Double Linked List

1. Membuat Simpul Baru

Untuk membuat node baru digunakan keyword new. Perintah ini digunakan untuk

mempersiapkan sebuah node dengan alokasi memorinya. Selanjutnya medan informasi pada node

tersebut diisi dengan data tertentu. Terakhir pointer prev dan next diisi dengan NULL.

Fungsi membuat simpul baru

Page 17: teori Struktur data full

14

void buat_baru()

{

baru = new(node);

cout<<"input nama : ";cin>>baru->nama;

cout<<"input umur : ";cin>>baru->umur;

cout<<"input tinggi : ";cin>>baru->tinggi;

baru->prev=NULL;

baru->next=NULL;

}

2. Menambah Simpul di Awal

Penambahan node baru yang akan diletakkan di node paling depan, perlu diperhatikan saat

pertama kali (data masih kosong), maka saat penambahan data dilakukan head/tail ditunjukkan

ke node baru tersebut. Sedangkan jika tidak kosong, data akan ditambahkan didepan head,

kemudian node baru akan berubah menjadi head.

B nextprev

head

NULL

tail

NULL NULL

head tailbaru

B nextprevNULL NULL

head tail

A nextprevNULL NULL

baru

B nextprev NULL

head tail

A nextprevNULL

baru

B nextprev NULL

head tail

A nextprevNULL

baru

Fungsi menambah simpul di awal void tambah_depan()

{

buat_baru();

if(head==NULL)

{

head=baru;

tail=baru;

}

else

{

baru->next=head;

head->prev=baru;

head=baru;

}

cout<<endl<<endl;

tampil();

}

3. Menambah Simpul di Belakang

Penambahan node di belakang akan selalu dikaitkan dengan tail dan kemudian node baru tersebut

akan menjadi tail.

Page 18: teori Struktur data full

15

B nextprev

head

NULL

tail

NULL NULL

head tailbaru

B nextprevNULL NULL

head tail

A nextprevNULL NULL

baru

B nextprevNULL

head tail

A nextprev NULL

baru

B nextprevNULL

head tail

A nextprev NULL

baru

Fungsi menambah simpul di belakang void tambah_belakang()

{

buat_baru();

if(head==NULL)

{

head=baru;

tail=baru;

}

else

{

tail->next=baru;

baru->prev=tail;

tail=baru;

}

cout<<endl<<endl;

tampil();

}

4. Menghapus Simpul di Awal

Menghapus node tidak boleh dilakukan jika keadaan node sedang ditunjuk oleh pointer, maka

harus dilakukan penggunakan suatu pointer lain yang digunakan untuk menunjuk node yang

akan dihapus, misalnya pointer hapus. Kemudian head harus ditunjukkan ke node sesudahnya

terlebih dahulu agar list tidak putus, sehingga node setelah head lama akan menjadi head baru.

Setelah itu barulah kemudian menghapus pointer hapus dengan menggunakan perintah delete.

Jika head masih NULL maka berarti data masih kosong!

ANULL B C D NULL

head tailhapus

BNULL C D NULL

tailhead

Fungsi menghapus simpul didepan void hapus_depan()

{

if (head==NULL)

cout<<"Kosong";

Page 19: teori Struktur data full

16

else if (head->next==NULL)

{

hapus=head;

head=NULL;

tail=NULL;

delete hapus;

}

else

{

hapus=head;

head=hapus->next;

head->prev=NULL;

delete hapus;

}

cout<<endl<<endl;

tampil();

}

Menghapus Simpul di Belakang

Menghapus simpul di belakang dibutuhkan satu buah pointer bantuan, misal pointer hapus, tidak

perlu melakukan perulangan untuk mencari node terakhir seperti pada single linked list. Pointer

hapus hanya perlu menunjuk pada pointer tail saja. Sebelum penghapusan node, tail harus

dipindahkan pada node sebelumnya. Selanjutnya pointer next dari tail diberi nilai NULL.

Kemudian langkah terakhir simpul hapus di-delete

ANULL B C D NULL

head tail hapus

ANULL B C

head tail

Fungsi menghapus simpul dibelakang

void hapus_belakang()

{

if (head==NULL)

cout<<"Kosong";

else if (head->next==NULL)

{

hapus=head;

head=NULL;

tail=NULL;

delete hapus;

}

else

{

hapus=tail;

tail=hapus->prev;

tail->next=NULL;

delete hapus;

}

cout<<endl<<endl;

tampil();

}

Page 20: teori Struktur data full

17

#include <iostream.h>

#include <conio.h>

#include <stdio.h>

int pil;

void pilih();

void buat_baru();

void tambah_belakang();

void tambah_depan();

void hapus_belakang();

void hapus_depan();

void tampil();

struct node

{

char nama [20];

int umur;

float tinggi;

node *prev, *next;

};

node *baru, *head=NULL, *tail=NULL,*hapus,*bantu;

void main()

{

do

{

clrscr();

cout<<"MENU DOUBLE LINKEDLIST"<<endl;

cout<<"1. Tambah Depan"<<endl;

cout<<"2. Tambah Belakang"<<endl;

cout<<"3. Hapus Depan"<<endl;

cout<<"4. Hapus Belakang"<<endl;

cout<<"5. Tampilkan"<<endl;

cout<<"6. Selesai"<<endl;

cout<<"Pilihan Anda : ";

cin>>pil;

pilih();

} while(pil!=6);

}

void pilih()

{

if(pil==1)

tambah_depan();

else if(pil==2)

tambah_belakang();

else if(pil==3)

hapus_depan();

else if(pil==4)

hapus_belakang();

else if(pil==5)

tampil();

else

cout<<"selesai";

}

void buat_baru()

{

baru = new(node);

cout<<"input nama : ";cin>>baru->nama;

cout<<"input umur : ";cin>>baru->umur;

cout<<"input tinggi : ";cin>>baru->tinggi;

baru->prev=NULL;

baru->next=NULL;

}

void tambah_belakang()

{

buat_baru();

if(head==NULL)

Page 21: teori Struktur data full

18

{

head=baru;

tail=baru;

}

else

{

tail->next=baru;

baru->prev=tail;

tail=baru;

}

cout<<endl<<endl;

tampil();

}

void tambah_depan()

{

buat_baru();

if(head==NULL)

{

head=baru;

tail=baru;

}

else

{

baru->next=head;

head->prev=baru;

head=baru;

}

cout<<endl<<endl;

tampil();

}

void hapus_depan()

{

if (head==NULL)

cout<<"Kosong";

else if (head->next==NULL)

{

hapus=head;

head=NULL;

tail=NULL;

delete hapus;

}

else

{

hapus=head;

head=hapus->next;

head->prev=NULL;

delete hapus;

}

cout<<endl<<endl;

tampil();

}

void hapus_belakang()

{

if (head==NULL)

cout<<"Kosong";

else if (head->next==NULL)

{

hapus=head;

head=NULL;

tail=NULL;

delete hapus;

}

else

{

hapus=tail;

tail=hapus->prev;

tail->next=NULL;

delete hapus;

Page 22: teori Struktur data full

19

}

cout<<endl<<endl;

tampil();

}

void tampil()

{

if (head==NULL)

cout<<"Kosong";

else

{

bantu=head;

while(bantu!=NULL)

{

cout<<" nama : "<<bantu->nama;

cout<<" umur : "<<bantu->umur;

cout<<" tinggi : "<<bantu->tinggi<<endl;

bantu=bantu->next;

}

}

getch();

}

Page 23: teori Struktur data full

20

BAB 4. STACK (TUMPUKAN)

Stack dapat diartikan sebagai tumpukan dari benda atau data yang seolah-olah diletakkan di atas

data yang lain dimana data yang pertama kali masuk akan terakhir. Secara sederhana sebuah

stack bisa digambarkan sebagai tumpukan buku yang disimpan dengan cara ditumpuk keatas.

Dimana buku yang pertama kali disimpan atau ditumpuk ada di paling bawah dan yang

selanjutnya ditumpuk diatasnya. Dan ketika kita melakukan pengambilan buku ototmatis buku

yang terkahir ditumpuk atau disimpan terakhir akan mejadi yang pertama diambil, istilah ini

kemudian disebut FILO (First In Last Out) dan bertambah atau berkurangnya data melalui satu

ujung yang sama yaitu ujung atas tumpukan (Top of Stack).

Ada 2 operasi dasar dari stack yang dapat dilakukan, yaitu :

1. Operasi push yaitu operasi menambahkan elemen pada urutan terakhir (paling atas).

2. Operasi pop yaitu operasi mengambil sebuah elemen data pada urutan terakhir dan

menghapus elemen tersebut dari stack.

Top 20

Top 15

15 Top 15

Top 10

10

10

10

Top = 0 push(10) push(15) push(20) pop(20)

kosong

Selain operasi dasar stack (push dan pop), ada lagi operasi lain yang dapat terjadi dalam

stack yaitu :

1. Proses deklarasi yaitu proses pendeklarasian stack.

2. Proses inisialisasi yaitu proses pembuatan stack kosong, biasanya dengan pemberian nilai

untuk top.

3. Proses cek kosong yaitu proses pemeriksaan apakah stack dalam keadaan kosong.

4. Proses cek penuh yaitu proses pemeriksaan apakah stack telah penuh.

Operasi-operasi stack secara lengkap adalah sebagai berikut :

1. Pendeklarasian stack dengan array Proses pendeklarasian stack adalah proses pembuatan struktur stack dalam memori.

Karena stack dapat direpresentasikan dalam 2 cara, maka pendeklarasian stack pun ada 2

yaitu:

Suatu stack memiliki beberapa bagian yaitu

a. top yang menunjuk posisi data terakhir (top)

b. elemen yang berisi data yang ada dalam stack. Bagian ini lah yang berbentuk array.

Deklarasi stack dengan array: struct stack

{

int elemen[10]; //elemen

int top;

};

2. Inisialisasi

Inisialisasi stack adalah proses pembuatan suatu stack kosong. Proses inisialisasi

untuk stack yang menggunakan array adalah dengan mengisi nilai field top dengan 0 (nol)

jika elemen pertama diawali dengan nomor 1. Kalau elemen pertama array dimulai dengan 0

maka top diisi dengan nilai -1.

p->top=-1

3. Operasi Cek Kosong Stack

Operasi ini digunakan untuk memeriksa apakah stack dalam keadaan kosong. Operasi ini

penting dilakukan dalam proses pop. Ketika suatu stack dalam keadaan kosong, maka proses

Page 24: teori Struktur data full

21

pop tidak bisa dilakukan. Operasi ini dilakukan hanya dengan memeriksa field top. Jika top

top bernilai -1, maka berarti stack dalam keadaan empty (kosong). if (p->top==-1)

{

cout<<"STACK kosong";

return -1;

}

4. Operasi Cek Penuh

Operasi ini berguna untuk memeriksa keadaan stack apakah sudah penuh atau belum.

Operasi ini akan memberikan nilai true (1) jika field top sama dengan size-1.

if(p->top==size-1)

cout<<"STACK penuh ";

5. Operasi Push

Operasi ini berguna untuk menambah suatu elemen data baru pada stack dan disimpan pada

posisi top yang akan mengakibatkan posisi top akan berubah. Langkah operasi ini adalah :

a. Periksa apakah stack penuh. Jika tidak penuh maka proses push dilaksanakan dan

jika stack penuh, maka proses push digagalkan.

b. Proses push-nya sendiri adalah dengan menambah field top dengan 1, kemudian

elemen pada posisi top diisi dengan elemen data baru. if(p->top==size-1)

cout<<"STACK penuh ";

else

p->elemen[++p->top]=value;

6. Operasi Pop

Operasi ini berguna untuk mengambil elemen terakhir (top) dan kemudian menghapus

elemen tersebut sehingga posisi top akan berpindah. Langkah operasi pop pada stack yang

menggunakan array adalah terlebih dahulu memeriksa apakah stack sedang keadaan kosong,

jika tidak kosong maka data diambil pada posisi yang ditunjuk oleh posisi top, kemudian

posisi top – 1.

if (p->top==-1)

{

cout<<"STACK kosong";

return -1;

}

else

return p->elemen[p->top--];

Program Lengkap:

#include<iostream.h>

#include<stdio.h>

#include<conio.h>

#define size 50

struct stack

{

int elemen[size];

int top;

};

typedef struct stack STACK;

void push(STACK *p,int value) // operasi push

{

if(p->top==size-1)

cout<<"STACK penuh ";

else

p->elemen[++p->top]=value;

}

int pop(STACK *p) //operasi pop

{

Page 25: teori Struktur data full

22

if (p->top==-1)

{

cout<<"STACK kosong";

return -1;

}

else

return p->elemen[p->top--];

}

void display (STACK *p) //menampilkan stack

{

int i;

if(p->top==-1)

cout<<"\n STACK kosong\n";

else

cout<<"\nIsi STACK adalah : \n";

for (i=p->top;i>=0; --i)

cout<<p->elemen[i]<<"\n";

}

void main()

{

STACK s ;

int x,c,i;

s.top=-1;

do

{

cout<<"MENU PILIHAN";

cout<<"\n1: Operasi PUSH\n";

cout<<"2: Operasi POP\n";

cout<<"3: Tampilkan Stack\n";

cout<<"4: Hapus Stasck\n";

cout<<"5: Keluar\n";

cout<<"\n\n Pilihan anda : ";cin>>c;

switch(c)

{

case 1:

cout<<"\nMasukkan Elemen Stack: ";cin>>x;

push (&s,x);

display(&s);

break;

case 2:

x=pop(&s);

if(x!=-1)

cout<<"\nMenghapus Element = "<<x;

break;

case 3:

display(&s);

break;

case 4:

if(s.top==-1)

cout<<endl<<"STACK kosong";

else

cout<<endl<<"STACK dihapus"<<endl;

//Menghapus STACK

for (i=s.top;i>=0; --i)

cout<<"Elemen yang dihapus adalah :

"<<pop(&s)<<endl;

s.top=-1;

}

getch();clrscr();

}while(c!=5);

}

Page 26: teori Struktur data full

23

Stack dengan animasi

#include <iostream.h>

#include <conio.h>

#include <stdlib.h>

int top,i;

char key,temp,e;

char stack[10];

void delay();

void pushanim()

{

for(i=0;i<=17; i++)

{

gotoxy(22+i,7);cout<<" ";

gotoxy(23+i,7);cout<<temp; delay();

}

for(i=1;i<=(14-top);i++)

{

delay();

gotoxy(40,6+i); cout<<" ";

gotoxy(40,7+i); cout<<temp;

}

}

void popanim(char temp)

{

for(i=1;i<=(14-top);i++)

{

delay();

gotoxy(40,22-i-top); cout<<" ";

gotoxy(40,21-i-top); cout<<temp;

}

for(i=1;i<=19;i++)

{

delay();

gotoxy(38+i,7); cout<<" ";

gotoxy(39+i,7); cout<<temp; delay();

}

gotoxy(58,7);cout<<" ";

}

void push(char e)

{

top=top+1;

stack[top]=e;

pushanim();

}

void pop(char e)

{

if(top !=0)

{

e=stack[top];

popanim(e);

top=top-1;

}

else

{

gotoxy(1,7); cout<<"stack telah kosong"<<endl;

gotoxy(1,7);

}

}

void main()

{

clrscr();

cout<<"Animasi Stack"<<endl;

cout<<"1.Push"<<endl;

cout<<"2.Pop"<<endl;

cout<<"3.Keluar"<<endl;

Page 27: teori Struktur data full

24

gotoxy(59,6); cout<<"=";

gotoxy(59,8); cout<<"=";

gotoxy(37,9); cout<<"|| ||";

for(i=1;i<=11;i++)

{

gotoxy(38,10+i);

if(i==11)

cout<<"|___|";

else

cout<<"| |";

}

top=0;

do

{

gotoxy(1,5);

cout<<"masukkan pilihan anda[1/2/3] : ";

key=getche();

if(int(key)==27 || key=='3')

break;

else if(key=='1')

{

if(top != 10)

{

gotoxy(1,7); cout<<"masukkan suatu huruf : ";

cin>>temp;

push(temp);

gotoxy(1,7); cout<<" ";

}

else

{

gotoxy(1,7); cout<<"stack penuh";

getch();

gotoxy(1,7); cout<<" ";

}

}

else if(key=='2')

pop(temp);

}while(1);

getch();

}

void delay()

{

for(int y=1;y<10000;y++)

for(int x=1;x<10000;x++)

for(int p=1;p<10000;p++)

cout<<"";

}

Page 28: teori Struktur data full

25

BAB 5. STACK DENGAN POINTER

Top

Top = NULL

23Top 25Top

23

22Top

25

23

25Top

23

Posis Awal Push(23) Push(25) Push(22) Pop(22)

Operasi-operasi stack secara lengkap adalah sebagai berikut :

7. Pendeklarasian stack dengan pointer Proses pendeklarasian stack adalah proses pembuatan struktur stack dalam memori.

Pendeklrasian dengan menggunakan pointer dibuat dua buah struktur yaitu data simpul yang

berupa data dan pointer yang menunjuk ke simpul selanjutnya dan yang kedua struktur stack

yang digunakan untuk menyimpan jumlah stack dan penunjuk posisi top dari stack:

Deklarasi Simpul/node : struct node

{

int bil;

struct node *next;

};

Deklarasi stack dengan array: struct stack

{

int jumlah;

struct node *top;

};

8. Inisialisasi

Inisialisasi stack adalah proses pembuatan suatu stack kosong. Proses inisialisasi

untuk stack yang menggunakan pointer adalah dengan mengisi nilai field top dengan NULL.

stack.top=NULL;

9. Operasi Cek Kosong Stack

Operasi ini digunakan untuk memeriksa apakah stack dalam keadaan kosong. Operasi ini

penting dilakukan dalam proses pop. Ketika suatu stack dalam keadaan kosong, maka proses

pop tidak bisa dilakukan. Operasi ini dilakukan hanya dengan memeriksa jumlah elemen

stack yang terbentuk. Jika jumlah bernilai 0, maka berarti stack dalam keadaan empty

(kosong). int cekKosong(stack *stack)

{

if(stack->jumlah==0)

return 1;

else

return 0;

}

Page 29: teori Struktur data full

26

10. Operasi Cek Penuh

Operasi ini berguna untuk memeriksa keadaan stack apakah sudah penuh atau belum.

Operasi ini akan memberikan nilai true (1) jika field top sama dengan size. int cekPenuh(stack *stack)

{

if(stack->jumlah==size)

return 1;

else

return 0;

}

11. Operasi Push

Operasi ini berguna untuk menambah suatu elemen data baru pada stack dan disimpan pada

posisi top yang akan mengakibatkan posisi top akan berubah. Langkah operasi ini adalah :

c. Periksa apakah stack penuh. Jika tidak penuh maka proses push dilaksanakan dan jika

stack penuh, maka proses push digagalkan.

d. Proses push-nya sendiri dilakukan dengan menyambungkan simpul baru->next sama

dengan stack->top, kemudian mengubah posisi top stack pada simpul baru dengan

stack->top sama dengan baru, kemudian menambah jumlah simpul sebesar 1 dengan

perintah stack->jumlah++. void Push(stack *stack)

{

node *baru;

if (cekPenuh(stack))

{

cout<<"stack full";

getch();

}

else

{

baru=new(node);

cout<<"\nmasukkan nilai yang ingin dipush ke stack: ";

cin>>baru->bil;

baru->next=stack->top;

stack->top=baru;

stack->jumlah++;

cout<<"\nproses push sukses";

getch();

}

}

12. Operasi Pop

Operasi ini berguna untuk mengambil elemen terakhir (top) dan kemudian menghapus

elemen tersebut sehingga posisi top akan berpindah. Langkah operasi pop pada stack yang

menggunakan pointer adalah terlebih dahulu memeriksa apakah stack sedang keadaan

kosong, jika tidak kosong maka:

a. Gunakan variabel bantu hapusPtr untuk membaca simpul top stack

b. Pindahkan posisi top stack pada posisi sebelumnya

c. Kurangi jumlah simpul pada stack sebasar 1

d. Hapus simpul hapusPrt

void Pop(stack *stack)

{

node *hapusPtr;

hapusPtr=stack->top;

if (cekKosong(stack))

{

cout<<"Stack Kosong";getch();

}

else

{

stack->top=stack->top->next;

stack->jumlah--;

delete hapusPtr;

cout<<"\nproses pop berhasil\n";

getch();

Page 30: teori Struktur data full

27

}

}

Program Lengkap:

#include<iostream.h>

#include<conio.h>

#define size 5

struct node

{

int bil;

struct node *next;

};

struct stack

{

int jumlah;

struct node *top;

};

int cekPenuh(stack *stack)

{

if(stack->jumlah==size)

return 1;

else

return 0;

}

int cekKosong(stack *stack)

{

if(stack->jumlah==0)

return 1;

else

return 0;

}

void Push(stack *stack)

{

node *baru;

if (cekPenuh(stack))

{

cout<<"stack full";

getch();

}

else

{

baru=new(node);

cout<<"\nmasukkan nilai yang ingin dipush ke stack: ";

cin>>baru->bil;

baru->next=stack->top;

stack->top=baru;

stack->jumlah++;

//cout<<"\nproses push sukses";

//getch();

}

}

void cetak(stack *stack)

{

node *bacaPtr;

bacaPtr=stack->top;

if(cekKosong(stack))

{

cout<<"\nstack kosong";

getch();

}

else

{

clrscr();

Page 31: teori Struktur data full

28

cout<<"\nTOP\n";

cout<<"---------\n";

while(bacaPtr!=NULL)

{

cout<<bacaPtr->bil<<endl;

cout<<"---------"<<endl;

bacaPtr=bacaPtr->next;

}

getch();

}

}

void Pop(stack *stack)

{

// int dataTop;

node *hapusPtr;

hapusPtr=stack->top;

if (cekKosong(stack))

{

cout<<"Stack Kosong";getch();

}

else

{

// dataTop=stack->top->bil;

stack->top=stack->top->next;

stack->jumlah--;

delete hapusPtr;

cout<<"\nproses pop berhasil\n";

getch();

}

}

void Top(stack *stack)

{

int dataTop;

if(cekKosong(stack))

{

cout<<"\ntop = NULL\n";

getch();

}

else

{

dataTop=stack->top->bil;

cout<<"\ntop = "<<dataTop<<endl;

getch();

}

}

void hapus(stack *stack)

{

node *bantuHapus;

while(stack->top!=NULL)

{

bantuHapus=stack->top;

stack->top=stack->top->next;

delete bantuHapus;

}

stack->jumlah=0;

}

void main()

{

stack stack;

stack.jumlah=0;

stack.top=NULL;

char pilih;

do

{

clrscr();

cout<<"MENU STACK"<<endl;

cout<<"[1]. Kosongkan Stack"<<endl;

Page 32: teori Struktur data full

29

cout<<"[2]. Push"<<endl;

cout<<"[3]. Pop"<<endl;

cout<<"[4]. Lihat Top Stack"<<endl;

cout<<"[5]. Tampilkan stack"<<endl;

cout<<"[6]. Keluar\n"<<endl;

cout<<"\npilihan: ";

cin>>pilih;

if(pilih=='1')

hapus(&stack);

if(pilih=='2')

{ Push(&stack);

cetak(&stack);}

if(pilih=='3')

{ Pop(&stack);

cetak(&stack);}

if(pilih=='4')

Top(&stack);

if(pilih=='5')

cetak(&stack);

}while(pilih!='6');

}

Page 33: teori Struktur data full

30

BAB 6. PENGURUTAN (SORTING)

Pengurutan didefinisikan sebagai suatu penyusunan ulang (pengorganisasian) himpunan obyek

dengan aturan tertentu. Jenis pengurutan:

1. Urut naik (ascending) yaitu jika data disusun mulai dari yang paling kecil hingga yang paling

besar.

2. Urut turun (descending) yaitu jika data disusun mulai dari yang paling besar hingga yang paling

kecil.

Keuntungan dari data yang sudah terurut adalah kemudahan dalam mencari data tertentu dan

kemudahan dalam melakukan perbaikan, disisipi data baru, dihapus serta digabungkan.

PENGURUTAN DENGAN PENYISIPAN LANGSUNG

Algoritma pengurutan langsung (ascending):

1. Mulai dari n=1

2. Bilangan ke-n diambil, cari posisi penyisipan yang sesuai dengan kriteria

3. Geser bilangan-bilangan mulai posisi penyisipan hingga bilangan ke-n

4. Sisipkan bilangan di posisi yang sesuai

5. Tambahkan n dengan 1

6. Ulangi langkah ke-2 sampai 5 hingga bernilai cacah bilangan

Algoritma:

For I 1 to n

X larik[i]

J i-1

While (x < larik[j])

Larik[j+1] larik[j]

J j-1

Endwhile

Larik[j+1] x

Endfor

Angka awal 10 5 12 0 32 56 34 6 11 99

proses 1 5 10 12 0 32 56 34 6 11 99

proses 2 5 10 12 0 32 56 34 6 11 99

proses 3 0 5 12 10 32 56 34 6 11 99

proses 4 0 5 10 12 32 56 34 6 11 99

proses 5 0 5 10 12 32 34 56 6 11 99

proses 6 0 5 6 10 12 32 34 56 11 99

proses 7 0 5 6 10 12 32 34 56 11 99

proses 8 0 5 6 10 11 12 32 34 56 99

terurut 0 5 6 10 11 12 32 34 56 99

Program

int j,x;

for (int i=1;i<10;i++)

{

x=larik[i];

j=i-1;

while (x<larik[j])

{

Page 34: teori Struktur data full

31

larik[j+1]=larik[j];

j--;

}

larik[j+1]=x;

}

PENGURUTAN DENGAN PEMILIHAN LANGSUNG

Cara kerja metode ini adalah dengan memilih data yang paling kecil (ascending) atau paling besar

(descending) kemudian meletakkannya pada posisi paling kiri dengan langkah-langkah penukaran.

Misalkan kita akan melakukan pengurutan ascending, maka pertama kali kita tunjuk data yang pertama.

Kemudian kita akan mencari data terkecil disebelah kanan data yang pertama tadi. Jika ada, maka data

yang terkecil kita tukar dengan data yang pertama, sehingga data pertama pasti memuat data yang

paling kecil. Selanjutnya kita lakukan hal yang sama untuk data ke-2 dan seterusnya.

Langkah-langkah :

1. Kerjakan langkah 2-4 untuk i=1 hinggai i=n-1

2. Tentukan lokasi = i

3. Kerjakan langkah4-5 untuk j=i+1 hingga j=n

4. Jika larik[lokasi] > larik[j], maka lokasi = j

5. Tukarkan larik[lokasi] dengan larik[i]

Algoritma:

For i 0 to n

Lokasi = i

For j=i+1 to n

If larik[lokasi] > larik[j]

Lokasi j

Endif

Endfor

//penukaran

Tampung larik[lokasi]

Larik[lokasi] = larik[i]

Larik[i] = tampung

Endfor

Angka awal

10 5 12 0 32 56 34 6 11 99

proses 1 0 10 12 5 32 56 34 6 11 99

proses 2 0 5 12 10 32 56 34 6 11 99

proses 3 0 5 6 10 32 56 34 12 11 99

proses 4 0 5 6 10 32 56 34 12 11 99

proses 5 0 5 6 10 11 56 34 12 32 99

proses 6 0 5 6 10 11 12 34 56 32 99

proses 7 0 5 6 10 11 12 32 56 34 99

proses 8 0 5 6 10 11 12 32 34 56 99

terurut 0 5 6 10 11 12 33 34 56 99

Program

int lokasi,temp;

for (int i=0;i<10;i++)

{

lokasi = i;

for(int j=i+1;j<10;j++)

{

if (larik[lokasi] > larik[j])

Page 35: teori Struktur data full

32

lokasi=j;

}

temp=larik[lokasi];

larik[lokasi]=larik[i];

larik[i]=temp;

}

PENGURUTAN DENGAN METODE GELEMBUNG (BUBLE SORT)

Metode ini cukup mudah dipelajari, tetapi metode ini sangat tidak efisien karena melibatkan langkah-

langkah perbandingan dan penukaran yang berjumlah sangat banyak. Ada dua cara yang dapat

dilakukan untuk mengimplementasikan metode gelembung. Pertama kita letakkan data terbesar

disebalah kanan, kemudian berturut-turut data tersebesar selanjutnya disebelah kirinya. Kedua, kita

letakkan data paling kecil disebelah kiri, kemudian kita letakkan data terkecil selanjutnya disebelah

kanannya. Kita akan membahas cara yang kedua :

Algoritma:

1. Kerjakan langkah untuk i=1 hingga n

2. Kerjakan langkah untuk j=n hingga j=1

3. Jika larik[j-1] > larik[j] maka tukarkan larik[j-1] dan larik[j]

For i=1 to n

For j= n to 0 step -1

If larik[j-1] > larik[j]

Temp larik[j]

Larik[j] larik[j-1]

Larik[j-1] temp

PROGRAM int temp;

for(int i=1;i<10;i++)

{

for(int j=9;j>=0;j--)

{

if(larik[j-1]>larik[j])

{

temp=larik[j];

larik[j]=larik[j-1];

larik[j-1]=temp;

}

}

}

Latihan :

Buat program lengkap

Program dalam fungsi

Page 36: teori Struktur data full

33

PENCARIAN (SEARCHING) 1. Pencarian Berurutan (Sequential Searching)

Pencarian Berurutan (Sequential Searching) merupakan metode yang paling mudah, tetapi juga paling tidak efisien. Metode ini berjalan lebih lambat dibandingkan metode-metode lainnya, tetapi metode ini merupakan metode yang paling mungkin diterapkan pada larik yang belum terurutkan. ALGORITMA

Ketemu false

I 0

While ((i<n) OR (Not Ketemu))

If data = larik[i]

Ketemu true

Posisi i

Endif

I=i+1

Endwhile

PROGRAM bool ketemu;

i=0;

ketemu=0;

while(i<10 || !ketemu)

{

if (cari==larik[i])

{

ketemu=1;

posisi=i;

}

i++;

}

2. Pencarian pada Larik Terurut Proses pencarian dilakukan dengan membandingkan elemen pertama, jika larik terurut naik (ascending), maka pencarian akan diterukan sepanjang data yang dicari masih lebih kecil dari elemen yang ada pada larik. Jika elemen larik sudah lebih besar maka pencarian bisa dihentikan, karena pasti data yang dicari tidak ada. ALGORITMA

Ketemu false

I 0

Do

If data = larik[i]

Ketemu true

Posisi i

Endif

I=i+1

While ((i<n) OR (Not Ketemu) OR (data < Larik[i])

PROGRAM

bool ketemu;

i=0;

ketemu=0;

do

{

if (cari==larik[i])

{

ketemu=1;

posisi=i;

}

i++;

}while((i<10) || (!ketemu) || (cari<larik[i]));

Page 37: teori Struktur data full

34

3. Pencarian Biner Metode pencarian biner hanya dapat digunakan pada larik yang sudah terurut. Cara kerja metode pencarian binner sebagai berikut:

1 5 6 10 11 12 32 34 56 99

Misalkan kita akan mencari posisi dari 56. Pertama larik diatas kita bagi menjadi 2 sub larik yaitu :

1 5 6 10 11

12 32 34 56 99

Sub larik 1 Sub larik 2 Kemudian jika data 56 dibandingkan dengan elemen terakhir pada sub larik 1 (yang bernilai 11). Jika data tersebut (56) lebih kecil dari elemen terakhir pada sub larik 1 (11), maka data akan dicari di sublarik 1. Ternyata tidak, maka data akan dicari di sub larik 2 dan sub larik 1 tidak perlu dihiraukan lagi. Proses diatas diulang lagi yaitu sub larik 2 dibagi dua lagi, sehingga menghasilkan sub larik sbb:

12 32 34

56 99

Sub larik 2.1 sub larik 2.2 Kita bandingkan data (56) dengan elemen terakhir sub larik 2.1 (yaitu 34). Ternyata data 56 Lebih besar dari elemen terakhir sub larik 2.1 (34), maka data yang akan dicari ada disub larik 2.2. Terakhir sub larik 2.2 perlu dipecah lagi hasilnya sbb:

56

99

Sub larik 2.2.1 Sub larik 2.2.2 Demikian dengan 4 interasi kita sudah dapat menemukan data yang kita cari. ALGORITMA

Ketemu false

Bawah 0

Atas n

While ((Bawah<=Atas) OR (Not Ketemu))

Tengah (Atas + Bawah) div 2

If (data < larik[tengah]

Atas = tengah -1

Else if (data > larik[tengah]

Bawah = tengah + 1

Else if (data = larik[tengah])

Ketemu = true

Posisi = tengah

Bawah = Atas +1

Endif

endwhile

PROGRAM

bool ketemu;

int atas, tengah, bawah;

ketemu=0; bawah=0; atas=10;

while((bawah<atas) || !ketemu)

{

tengah=(atas+bawah)/2;

if(cari < larik[tengah])

atas=tengah-1;

else if (cari > larik[tengah])

bawah=tengah+1;

else if (cari == larik[tengah])

{

ketemu=1;

posisi=tengah;

bawah=atas+1;

}

}

Page 38: teori Struktur data full

35

BAB 8. TREE (POHON) Struktur pada tree (pohon) tidak linear seperti pada struktur linked list, stack, dan queue. Setiap node pada tree mempunyai tingkatan, yaitu orang tua (parent) dan anak (child). Struktur ini sebenarnya merupakan bentuk khusus dari struktur tree yang lebih umum, setiap orang tua hanya memiliki dua anak sehingga disebut pohon biner (binary tree), yaitu anak kiri dan anak kanan. ISTILAH DASAR Tree merupakan salah satu bentuk struktur data tidak linear yang menggambarkan hubungan yang bersifat hirarkis (hubungan one to many) antara elemen-elemen. Tree dapat didefinisikan sebagai kumpulan simpul/node dengan satu elemen khusus yang disebut root dan node, disebut sub tree/sub pohon atau cabang. Sehingga secara sederhana pohon bisa didefinisikan sebagai kumpulan elemen yang salah satu elemennya disebut dengan akar (root) dan elemen yang lainnya (simpul), terpecah menjadi sejumlah himpunan yang saling tidak berhubungan satu dengan yang lainnya. Binary Tree adalah tree dengan syarat bahwa tiap node hanya boleh memiliki maksimal dua subtree dan kedua subtree tersebut harus terpisah. Maka tiap node dalam binary tree hanya boleh memiliki paling banyak dua child.

A

C

D H

B

G J

Keterangan : ·Left Child : B, D, H, ... ·Right Child : C, G, J, … Jenis Binary Tree Full Binary Tree Binary Tree yang tiap nodenya (kecuali leaf) memiliki dua child dan tiap sub tree harus mempunyai panjang path yang sama.

A

C

D E

B

F G

Complete Binary Tree Mirip dengan Full Binary Tree, namun tiap subtree boleh memiliki panjang path yang berbeda. Node kecuali leaf memiliki 0 atau 2 child.

A

C

D E

B

Skewed Binary Tree Binary Tree yang semua nodenya (kecuali leaf) hanya memiliki satu child.

Page 39: teori Struktur data full

36

A

D

B

Operasi Binary Tree 1. Deklarasi Tree

Tree tersusun oleh node-node, maka yang perlu kita deklarasikan adalah komponen node itu sendiri. Dalam contoh dibawah, akan kita namai Node. Sebelumnya perlu kita lihat bahwa untuk mewujudkan implementasi node ke dalam bahasa pemrograman, diperlukan sebuah struktur yang memiliki susunan berikut ini:

struct Node

{

int data;

Node *kiri;

Node *kanan;

};

2. Inisialisasi Tree

Saat pertama membuat sebuah pohon biner, asumsi awal adalah pohon itu belum bertumbuh, belum

memiliki node sama sekali, sehingga masih kosong. Oleh karena itu perlu kita tambahkan kode berikut

pada baris awal fungsi Main:

Node *pohon;

pohon = NULL;

3. Menambah Node pada Tree

Karena pohon yang kita buat merupakan sebuah pohon biner, maka untuk menambahkan sebuah node, secara otomatis penambahan tersebut mengikuti aturan penambahan node pada pohon biner: 1. Jika pohon kosong, maka node baru ditempatkan sebagai akar pohon. 2. Jika pohon tidak kosong, maka dimulai dari node akar, dilakukan proses pengecekan berikut:

a. Jika nilai node baru lebih kecil dari nilai node yang sedang dicek, maka lihat ke kiri node tersebut. Jika kiri node tersebut kosong (belum memiliki kiri), maka node baru menjadi kiri node yang sedang dicek. Seandainya kiri node sudah terisi, lakukan kembali pengecekan a dan b terhadap node kiri tersebut. Pengecekan ini dilakukan seterusnya hingga node baru dapat ditempatkan.

b. Jika nilai node baru lebih besar dari nilai node yang sedang dicek, maka lihat ke kanan node tersebut. Jika kanan node tersebut kosong (belum memiliki kanan), maka node baru menjadi kanan node yang sedang dicek. Seandainya kanan node sudah terisi, lakukan kembali pengecekan a dan b terhadap node kanan tersebut. Pengecekan ini dilakukan seterusnya hingga node baru dapat ditempatkan.

Proses penambahan ini diimplementasikan secara rekursif pada fungsi berikut: void tambah(Node **root,int databaru)

{

if((*root) == NULL)

{

Node *baru;

baru = new Node;

baru->data = databaru;

baru->kiri = NULL;

baru->kanan = NULL;

(*root) = baru;

(*root)->kiri = NULL;

(*root)->kanan = NULL;

cout<<"Data bertambah!";

getch();

}

else

if(databaru < (*root)->data)

tambah(&(*root)->kiri,databaru);

else

if(databaru > (*root)->data)

tambah(&(*root)->kanan,databaru);

else

if(databaru == (*root)->data)

Page 40: teori Struktur data full

37

{ cout<<"Data sudah ada!";

getch();

}

}

Variabel **root menunjukkan node mana yang sedang dicek saat ini, untuk itu saat pemanggilan fungsi

ini, variabel **root kita beri nilai pointer yang menunjuk ke node akar, yaitu pohon.

tambah(&pohon,data);

4. Membaca dan Menampilkan data pada Tree/Traverse PreOrder : cetak isi node yang dikunjungi, kunjungi Left Child, kunjungi Right Child. Kunjungan pre-order dilakukan mulai dari akar pohon, dengan urutan: 1. Cetak isi (data) node yang sedang dikunjungi 2. Kunjungi kiri node tersebut,

a. Jika kiri bukan kosong (tidak NULL) mulai lagi dari langkah pertama, terapkan untuk kiri tersebut. b. Jika kiri kosong (NULL), lanjut ke langkah ketiga.

3. Kunjungi kanan node tersebut, a. Jika kanan bukan kosong (tidak NULL) mulai lagi dari langkah pertama, terapkan untuk kanan

tersebut. b. Jika kanan kosong (NULL), proses untuk node ini selesai, tuntaskan proses yang sama untuk node

yang dikunjungi sebelumnya. void preOrder(Node *root)

{

if(root != NULL)

{

cout<<root->data<<" ";

preOrder(root->kiri);

preOrder(root->kanan);

}

}

InOrder : kunjungi Left Child, cetak isi node yang dikunjungi, kunjungi Right Child. 1. Kunjungi kiri node tersebut,

a. Jika kiri bukan kosong (tidak NULL) mulai lagi dari langkah pertama, terapkan untuk kiri tersebut. b. Jika kiri kosong (NULL), lanjut ke langkah kedua.

2. Cetak isi (data) node yang sedang dikunjungi 3. Kunjungi kanan node tersebut,

a. Jika kanan bukan kosong (tidak NULL) mulai lagi dari langkah pertama, terapkan untuk kanan tersebut.

b. Jika kanan kosong (NULL), proses untuk node ini selesai, tuntaskan proses yang sama untuk node yang dikunjungi sebelumnya. void inOrder(Node *root)

{

if(root != NULL)

{

inOrder(root->kiri);

cout<<root->data<<" ";

inOrder(root->kanan);

}

}

PostOrder : kunjungi Left Child, kunjungi Right Child, cetak isi node yang dikunjungi. 1. Kunjungi kiri node tersebut,

a. Jika kiri bukan kosong (tidak NULL) mulai lagi dari langkah pertama, terapkan untuk kiri tersebut. b. Jika kiri kosong (NULL), lanjut ke langkah kedua.

2. Kunjungi kanan node tersebut, a. Jika kanan bukan kosong (tidak NULL) mulai lagi dari langkah pertama, terapkan untuk kanan

tersebut. b. Jika kanan kosong (NULL), lanjut ke langkah ketiga.

3. Cetak isi (data) node yang sedang dikunjungi. Proses untuk node ini selesai, tuntaskan proses yang sama untuk node yang dikunjungi sebelumnya.

void postOrder(Node *root)

{

if(root != NULL)

{

postOrder(root->kiri);

postOrder(root->kanan);

Page 41: teori Struktur data full

38

cout<<root->data<<" ";

}

}

Program Lengkap #include <stdio.h>

#include <conio.h>

#include <iostream.h>

struct Node

{

int data;

Node *kiri;

Node *kanan;

};

void tambah(Node **root,int databaru)

{

if((*root) == NULL)

{

Node *baru;

baru = new Node;

baru->data = databaru;

baru->kiri = NULL;

baru->kanan = NULL;

(*root) = baru;

(*root)->kiri = NULL;

(*root)->kanan = NULL;

cout<<"Data bertambah!";

getch();

}

else

if(databaru < (*root)->data)

tambah(&(*root)->kiri,databaru);

else

if(databaru > (*root)->data)

tambah(&(*root)->kanan,databaru);

else

if(databaru == (*root)->data)

{ cout<<"Data sudah ada!";

getch();

}

}

void preOrder(Node *root)

{

if(root != NULL)

{

cout<<root->data<<" ";

preOrder(root->kiri);

preOrder(root->kanan);

}

}

void inOrder(Node *root)

{

if(root != NULL)

{

inOrder(root->kiri);

cout<<root->data<<" ";

inOrder(root->kanan);

}

}

void postOrder(Node *root)

{

if(root != NULL)

{

postOrder(root->kiri);

postOrder(root->kanan);

Page 42: teori Struktur data full

39

cout<<root->data<<" ";

}

}

void main()

{

int data;

Node *pohon;

pohon = NULL;

char pil;

do

{

clrscr();

cout<<"1. Tambah\n";

cout<<"2. Lihat Pre-order\n";

cout<<"3. Lihat In-order\n";

cout<<"4. Lihat Post-order\n";

cout<<"5. Keluar\n";

cout<<"Masukkan pilihan anda (1-5) : ";

cin>>pil;

if(pil!='1' && pil !='2' && pil !='3' && pil!='4' && pil!='5' )

cout<<"\n\nAnda salah pilih...\n";

else

{

if(pil=='1')

{

cout<<"\n";

cout<<"\nData baru : ";

cin>>data;

tambah(&pohon,data);

}

else

{

if(pil=='2')

{

cout<<"\n";

if(pohon!=NULL)

preOrder(pohon);

else

cout<<"Masih kosong!";

getch();

}

else

{

if(pil=='3')

{

cout<<"\n";

if(pohon!=NULL)

inOrder(pohon);

else

cout<<"Masih kosong!";

getch();

}

else

{

if(pil=='4')

{

cout<<"\n";

if(pohon!=NULL)

postOrder(pohon);

else

cout<<"Masih kosong!";

getch();

}

}

}

}

}

}

while(pil!='5');

Page 43: teori Struktur data full

40

}

void BinaryTree::remove(int d) { //Tempat element bool found = false; if(isEmpty()) { cout<<" This Tree is empty! "<<endl; return; } tree_node* curr; tree_node* parent; curr = root; while(curr != NULL) { if(curr->data == d) { found = true; break; } else { parent = curr; if(d>curr->data) curr = curr->right; else curr = curr->left; } } if(!found) { cout<<" Data not found! "<<endl; return; } // 3 pilihan : // 1. Kita bisa menghapus cabang node (leaf node) // 2. Kita bisa menghapus sebuah node dengan satu anaknya // 3. Kita bisa menghilangkan sebuah node dengan dua anaknya // Node dengan satu anaknya (cabang dari induknya) if((curr->left == NULL && curr->right != NULL)|| (curr->left != NULL && curr->right == NULL)) { if(curr->left == NULL && curr->right != NULL) { if(parent->left == curr) { parent->left = curr->right; delete curr; } else { parent->right = curr->right; delete curr; } } else // untuk cabang bagian kiri, bukan untuk cabang bagian kanan { if(parent->left == curr) { parent->left = curr->left; delete curr;

Page 44: teori Struktur data full

41

} else { parent->right = curr->left; delete curr; } } return; } //Kita bisa melihat pada pohon node (leaf node) if( curr->left == NULL && curr->right == NULL) { if(parent->left == curr) parent->left = NULL; else parent->right = NULL; delete curr; return; } //Node dengan dua anaknya (cabang dari induknya) // mengganti atau menempatkan lagi dengan nilai terkecil pada anak pohon bagian kanan if (curr->left != NULL && curr->right != NULL) { tree_node* chkr; chkr = curr->right; if((chkr->left == NULL) && (chkr->right == NULL)) { curr = chkr; delete chkr; curr->right = NULL; } else // anak bagian kanan merupakan anak-anak dari induknnya (children) { //jika anak kanan node merupakan anak bagian kiri //memindahkan semua bagian bawah cabang ke tempat element terkecil if((curr->right)->left != NULL) { tree_node* lcurr; tree_node* lcurrp; lcurrp = curr->right; lcurr = (curr->right)->left; while(lcurr->left != NULL) { lcurrp = lcurr; lcurr = lcurr->left; } curr->data = lcurr->data; delete lcurr; lcurrp->left = NULL; } else { tree_node* tmp; tmp = curr->right; curr->data = tmp->data; curr->right = tmp->right; delete tmp; } } return; } }