BAB I
BAB I
POINTER, STRUCTURE, REKURSIF
POINTER, STRUCTURE, REKURSIF
1.1
1.1
Pengertian
Pengertian Pointer
Pointer
Pointer adalah suatu variabel penunjuk, berisi nilai yang menunjuk alamat Pointer adalah suatu variabel penunjuk, berisi nilai yang menunjuk alamat suatu lokasi memori tertentu. Jadi pointer tidak berisi nilai data, melainkan berisi suatu lokasi memori tertentu. Jadi pointer tidak berisi nilai data, melainkan berisi suatu alamat memori atau null, jika pointer tidak berisi data maka disebut null suatu alamat memori atau null, jika pointer tidak berisi data maka disebut null pointer.
pointer.
Pointer yang tidak diinisialisasi disebut dangling pointer. Pointer yang tidak diinisialisasi disebut dangling pointer.
Lokasi memori tersebut bisa diwakili dengan sebuah variabel at
Lokasi memori tersebut bisa diwakili dengan sebuah variabel at au dapat jugaau dapat juga berupa nilai alamat memori secara langsung. Ilustrasi pointer :
berupa nilai alamat memori secara langsung. Ilustrasi pointer :
Kita me
Kita memiliki variabel X yang berisi nilai karakter “a”, maka olehmiliki variabel X yang berisi nilai karakter “a”, maka oleh compilercompiler C++ nilai “a” ini akan disimpan di suatu alamat tertentu di memori. Sehingga C++ nilai “a” ini akan disimpan di suatu alamat tertentu di memori. Sehingga alamat variabel X ini dapat diakses dengan menggunakan statement &X.
alamat variabel X ini dapat diakses dengan menggunakan statement &X. Jika kita ingin menyimpan alamat dari
Jika kita ingin menyimpan alamat dari variabel X ini, variabel X ini, kita dapat menggunakankita dapat menggunakan suatu variabel misalnya
suatu variabel misalnya int alamat_x = &x; int alamat_x = &x;
Maka alamat_x adalah suatu variabel yang berisi alamat dimana nilai X, yaitu Maka alamat_x adalah suatu variabel yang berisi alamat dimana nilai X, yaitu 20 disimpan. Variabel alamat_x disebut variabel pointer atau sering disebut 20 disimpan. Variabel alamat_x disebut variabel pointer atau sering disebut dengan pointer saja.
dengan pointer saja.
Contoh penerapan pointer pada program Contoh penerapan pointer pada program
Sour
BAB I
BAB I
POINTER, STRUCTURE, REKURSIF
POINTER, STRUCTURE, REKURSIF
1.1
1.1
Pengertian
Pengertian Pointer
Pointer
Pointer adalah suatu variabel penunjuk, berisi nilai yang menunjuk alamat Pointer adalah suatu variabel penunjuk, berisi nilai yang menunjuk alamat suatu lokasi memori tertentu. Jadi pointer tidak berisi nilai data, melainkan berisi suatu lokasi memori tertentu. Jadi pointer tidak berisi nilai data, melainkan berisi suatu alamat memori atau null, jika pointer tidak berisi data maka disebut null suatu alamat memori atau null, jika pointer tidak berisi data maka disebut null pointer.
pointer.
Pointer yang tidak diinisialisasi disebut dangling pointer. Pointer yang tidak diinisialisasi disebut dangling pointer.
Lokasi memori tersebut bisa diwakili dengan sebuah variabel at
Lokasi memori tersebut bisa diwakili dengan sebuah variabel at au dapat jugaau dapat juga berupa nilai alamat memori secara langsung. Ilustrasi pointer :
berupa nilai alamat memori secara langsung. Ilustrasi pointer :
Kita me
Kita memiliki variabel X yang berisi nilai karakter “a”, maka olehmiliki variabel X yang berisi nilai karakter “a”, maka oleh compilercompiler C++ nilai “a” ini akan disimpan di suatu alamat tertentu di memori. Sehingga C++ nilai “a” ini akan disimpan di suatu alamat tertentu di memori. Sehingga alamat variabel X ini dapat diakses dengan menggunakan statement &X.
alamat variabel X ini dapat diakses dengan menggunakan statement &X. Jika kita ingin menyimpan alamat dari
Jika kita ingin menyimpan alamat dari variabel X ini, variabel X ini, kita dapat menggunakankita dapat menggunakan suatu variabel misalnya
suatu variabel misalnya int alamat_x = &x; int alamat_x = &x;
Maka alamat_x adalah suatu variabel yang berisi alamat dimana nilai X, yaitu Maka alamat_x adalah suatu variabel yang berisi alamat dimana nilai X, yaitu 20 disimpan. Variabel alamat_x disebut variabel pointer atau sering disebut 20 disimpan. Variabel alamat_x disebut variabel pointer atau sering disebut dengan pointer saja.
dengan pointer saja.
Contoh penerapan pointer pada program Contoh penerapan pointer pada program
Sour
Tamp
Tampilil an Han H asasilil
1.2
1.2
Perbedaan P
Perbedaan Pointer Dengan
ointer Dengan Variabel
Variabel Biasa
Biasa
1.3
1.3
Operator
Operator Pointer
Pointer
1.4 Aturan
1.4 Aturan
Variabel pointer dapat dideklarasikan dengan tipe dapat apapun. Variabel pointer dapat dideklarasikan dengan tipe dapat apapun. Pendeklarasian variabel pointer dengan tipe data tertentu digunakan untuk Pendeklarasian variabel pointer dengan tipe data tertentu digunakan untuk menyimpan alamat memori yang berisi data sesuai dengan tipe data yang menyimpan alamat memori yang berisi data sesuai dengan tipe data yang dideklarasikan, bukan untuk berisi nilai bertipe data tertentu.
dideklarasikan, bukan untuk berisi nilai bertipe data tertentu.
Tipe data digunakan sebagai lebar data untuk alokasi memori (misalnya char Tipe data digunakan sebagai lebar data untuk alokasi memori (misalnya char berarti lebar datanya 1 byte, dst).
Jika suatu variabel pointer dideklarasikan bertipe flat, berarti variabel pointer tersebut hanya bisa digunakan untuk menunjuk alamat memori yang berisi nilai bertipe flat juga.
1.5 Operasi Pada Pointer
Antar variabel pointer dapat dilakukan operasi assingment.
Contoh 1 : assignment dan sebuah alamat dapat ditunjuk oleh lebih dari 1 pointer.
Sour ce Code
Tampil an H asil
Contoh 2 : mengisi variabel dengan nilai yang ditunjuk oleh sebuah variabel pointer.
Tampil an H asil
Contoh 3 : mengoperasikan isi variabel dengan menyebut alamatnya dengan pointer
Sour ce Code
Tampil an H asil
Tampil an H asil
1.6 Pointer Pada Array
Pada array, pointer hanya perlu menunjuk pada alamat elemen pertama saja karena letak alamat array sudah berurutan pada memori. Variabel pointer Han perlu increment.
Lihat seperti pada contoh program dibawah ini!
Sour ce Code
1.7 Pengertian Structure
Structure(struktur) adalah kumpulan elemen-elemen data yang digabungkan menjadi satu kesatuan. Masing-masing elemen data tersebut dikenal dengan sebutan field. Field data tersebut dapat memiliki tipe data yang sama ataupun berbeda. Walaupun field-field tersebut berada dalam satu kesatuan,
masing-masing field tersebut tetap dapat diakses secara individual.
Field-field tersebut digabungkan menjadi satu dengan tujuan untuk kemudahan dalam operasinya. Misalnya anda ingin mencatat data-data mahasiswa dan pelajar dalam sebuah program. Untuk membedakannya anda dapat membuat sebuah struct mahasiswa yang terdiri dari field nama, mim, program studi, dan ipk. Serta sebuah record pelajar yang terdiri dari field-field nama, nim, alamat, dan nilai. Dengan demikian akan lebih mudah untuk membedakan keduanya. Bentuk umum : struct nama_struct { tipe_data field1; tipe_data field2; tipe_data fieldN; }; Contoh : struct mahasiswa {
char nim[11], nama[50]; char alamat[100];
float ipk; };
1.8 Penggunaan dan Pengaksesan Elemen Terstruktur
Untuk menggunakan struktur, tulis nama struktur beserta dengan fieldnya yang dipisahkan dengan tanda titik (“ . “). Misalnya anda ingin menulis mim seorang mahasiswa ke layar maka penulisan yang benar adalah seba gai berikut :
 Mahasiswa.nim = “1418126”;
 Cout << mahasiswa.nim;
Jika x adalah pointer bertipe mahasiswa* maka field dari x dapat diakses dengan mengganti tanda titik dengan tanda panah (“ -> “).
 cout << mahasiswa->nim; Contoh Program Struct!
Tampil an H asil
1.9 Pengertian Rekursif
Rekursif adalah salah satu metode dalam dunia matematika, Diana definisi sebuah fungsi mengandung fungsi itu sendiri. Dalam dunia pemrograman, rekursi diimplementasikan dalam sebuah fungsi yang memanggil dirinya sendiri dan prosesnya terjadi secara berulang-ulang.
1.10 Implementasi Rekursif
1.10.1 Faktorial n != 1 if n = 0 anchor n != n*(n-1)! If n > 0 inductive step 0! = 1 2! = 2*(2-1)! = 2*1! = 2*1 = 2 3! = 3*(3-1)! = 3*2! = 3*2 = 6 1! = 1*(1-1)! = 1*0! = 1*1 = 1 NB : 0! = 1Tabel peningkatan nilai faktorial
Contoh implementasi rekursif dari fungsi faktorial :
Sour ce Code
Tampil an H asil
1.10.2 Fibonacci
Fibonacci adalah kumpulan deret angka seperti berikut ini “1, 1, 2, 3, 5, 8, 13 , 21, 34, 55, ...”. setiap bilangan setelah bilangan kedua merupakan jumlah dari. Dengan demikian 2 dari 1+1, 3 dari 2+1, 5 dari 3+2, dan demikian seterusnya yang merupakan definisi rekursif dan secara sistematis dijabarkan sebagai berikut :
Jika n = 0, maka Fn = 0, jika n = 1, maka Fn = 1
Jika n > 1, maka Fn = F(n-1)+F(n-2)
Implementasi dari fungsi fibonacci secara logika ekuivalen dengan translasi langsung dari definisi diatas. Karena Fn = n untuk n < 2, kita dapat menyederhanakan dengan pernyataan If.
Contoh : program rekursif dari fungsi fibonacci
Tampil an hasil
1.10.3 Menara Hanoi
Permainan menara Hanoi merupakan contoh klasik Diana solusinya memerlukan rekursif. Permainan ini terdiri dari papan dengan 3 tiang yang diberi label A, B, dan C, dan tumpukan cakram yang disusun dari besar ke kecil (dari bawah ke atas) pada tiang A. Aturannya adalah tidak boleh ada cakram yang lebih besar di atas cakram kecil. Tujuan permainan ini adalah untuk memindahkan seluruh cakram dari tiang A ke tiang C, satu per satu dengan melalui menara B sebagai menara tampungan.
Solusi umum untuk permainan ini pada dasarnya adalah rekursif : Bagian I : Pindahkan n-1 cakram yang lebih kecil dari A ke B. Bagian II : Pindahkan sisa cakram dari A ke C.
Bagian III : Pindahkan n-1 cakram dari B ke C.
Bagian I dan III adalah rekursif. Terapkan solusi lengkap n-1 cakram. Basis dari rekursif ini adalah kasus Diana n = 0, pada kasus ini tidak ada yang dikerjakan.
Contoh : Program Rekursif dari Menara Hanoi
Tugas !
Buatlah program faktorial dengan ketentuan : 1. Banyak angka diinputkan manual oleh user 2. Dapat diulang kembali
3. Untuk script dapat dikreasikan sendiri, tidak boleh sama dengan modul
BAB II
STACK, QUEUE
2.1 Pengertian Stack
Stack atau tumpukan adalah saru struktur data yang penting dalam pemrograman. Stack mempunyai sifat LIFO (Last In First Out) dimana benda yang terakhir masuk ke dalam stack akan menjadi benda pertama yang dikeluarkan dari stack. Contohnya : ketika kita menumpuk Compo di posisi terakhir, maka Compo akan menjadi elemen teratas dalam tumpukan. Sebaliknya, ketika kita menumpuk Televisi pada saat pertama kali, ma ka elemen Televisi ini menjadi elemen terbawah dari tumpukan. Dan jika kita mengambil elemen dari tumpukan, maka secara otomatis akan terambil elemen teratas , yaitu Compo. Ilustrasinya dapat dilihat pada gambar dibawah ini.
2.2 Operasi-operasi / Fungsi Stack
Push : Digunakan untuk menambah item pada stack dan ditempatkan pada tumpukan paling atas
Pop : Digunakan untuk mengambil item pada stack pada tumpukan paling atas
Clear : Digunakan untuk mengosongkan stack
Is Empty : Fungsi yang digunakan untuk mengecek apakah stack sudah kosong
Is Full : Fungsi yang digunakan untuk mengecek apakah stack sudah penuh
2.3 Stack Dengan Struktur Array
1. Mendefinisikan stack dengan menggunakan struct
2. Mendefinisikan MAX_STACK untuk maksimum isi stack
3. Membuat variabel array data sebagai implementasi stack secara nyata 4. Mendeklarasikan operasi-operasi / function di atas dan membuat
2.4 Deklarasi Stack dengan Struct dan Array
typedef struct Stack{
int top;
char data[10][10];
//misalkan : data adalah array of string //berjumlah 10 data, masing-masing string //menampung maksimal 10 karakter
};
Deklarasi / buat variabel dari Struct
Deklarasi MAX_STACK #define MAX_STACK 10
//hati-hato mulai dari 0, jadi 0-9 bukan 1-10
2.5 Inisialisasi Stack
Pada mulanya isi top dengan -1, karena array dalam C dimulai dari 0, yang berarti stack adalah KOSONG! Top adalah suatu variabel penanda dalam Stack yang menunjukkan elemen teratas Stack sekarang. Top Of Stack akan selalu bergerak hingga mencapai Max Of Stack sehingga menyebabkan Stack PENUH!
Ilustrasi stack pada saat inisialisasi seperti pada gambar dibawah ini :
2.6 Fungsi Is Full
Untuk memeriksa apakah stack sudah penus? Cukup dengan cara memeriksa Top of Stack, jika sudah sama dengan MAX_STACK-1 maka dapat dinyatakan bahwa stack yang ada sudah penuh, tetapi jika masih lebih kecil dari MAX_STACK-1 maka dapat dinyatakan bahwa stack belum penuh. Untuk ilustrasinya dapat dilihat seperti pada gambar dibawah ini :
2.7 Fungsi Push
Untuk memasukkan elemen ke stack, selalu menjadi elemen teratas stack. Tambah satu (increment) nilai Top of Stack terlebih dahulu setiap kali ada penambahan elemen stack, asalkan stack masih belum penuh, kemudian isikan nilai baru ke stack berdasarkan index Top of Stack setelah ditambah sat u seperti pada gambar dibawah ini :
2.8 Fungsi POP
Untuk mengambil elemen teratas dari stack, ambil dahulu nilai elemen teratas stack dengan mengakses Top of Stack, tumpukan nilai yang akan diambil
terlebih dahulu, baru didecrement (dikurangi) nilai Top of Sta ck sehingga jumlah elemen stack berkurang seperti pada gambar dibawah ini :
Sintax program fungsi POP
2.9 Fungsi Print
Untuk menampilkan semua elemen-elemen stack. Dengan cara looping semua nilai array secara erbalik, karena kita harus mengakses dari indeks array tertinggi terlebih dahulu baru ke indeks yang paling kecil seperti pada gambar dibawah :
Sintaks program fungsi Print :
void TampilStack() {
for (int i = tumpuk.top; i >= 0; i--) {
cout << "Data : " << tumpuk.data[i]; }
}
2.10 Studi Kasus
Pembuatan kalkulator Scientific, misalkan operasi : 3 + 2 * 5, operasi berikut disebut dengan notasi infiks. Notasi infiks tersebut harus diubah terlebih dahulu menjadi notasi postfix 2 5 * 3 +. Kemudian diimplementasikan dalam stack sebagai berikut : stacl soal (dalam bentuk postfix) dan stack hasil (masih kosong) seperti pada gambar dibawah ini :
Algoritma Pop Stack :
1. Jika berupa operan, maka masukkan ke stack hasil 2. Jika berupa operator, maka :
a. Pop nilai pertama dari stack hasil b. Pop nilai kedua dari stack hasil
c. Lakukan operasi sesuai dengan operator yang didapat. Misalnya untuk contoh diatas pada gambar dibawah ini
Operator * di pop dari stack soal, pop stack hasil dua kali, yaitu 5 dan 2. Kemudian simpan 5 kedalam variabel misalnya a, dan 2 kedalam variabel b. Lalu lakukan operasi sesuai dengan operatornya, b<operator>a. Jadi b * a, yaitu 2 * 5, kemudian hasilnya disimpan lagi ke dalam stack hasil seperti pada gambar dibawah ini :
Kemudian lakukan langkah yang sama sampai selesai.
Pada contoh : operator + di pop dari stack soal, pop stack hasil dua kali, yaitu 3 disimpan pada variabel a, dan 2 disimpan pada variabel b. Kemudian dilakukan operasi sesuai dengan operatornya, b<operator>a. Jadi b + a, yaitu 8 + 3 = 11
Contoh, cara lain :
Penghitungan : ((1 + 2) * 4) + 3 dapat ditulis berurut ke bawah secara postfix dengan keuntungan tanpa preseden pada aturan dan pokok masalahnya :
1 2 + 4 * 3 +
Persamaan dimasukkan dari kiri ke kanan menggunakan stack : 1. Push operandi yang dihitung dan
2. Pop Two Operand dan nilai hasil operasi penghitungan
3. Push hasil penghitungan dengan langkah seperti diilustrasikan sebagai berikut ini :
Hasil akhir, 15 dan tinggalkan pada top stack dan selesai menghitung. Contoh pemanfaatan stack
 Notasi Infox Prefix  Notasi Infix Postfix
2.11 Notasi Aritmetik (Infix, Postfix, Prefix)
Notasi aritmetika biasa ditulis dalam notasi Infix, misal A+B+C. Notasi infix mudah dimengerti oleh manusia, hanya saja dalam notasi infix perlu diperhatikan prioritas pengerjaan karena berhubungan dengan hierarki operator pada komputer. Prioritas pengerjaannya adalah :
1. Tanda kurung : ( ... )
2. Eksponensial atau pangkat : ^ 3. Perkalian, pembagian : *, /
4. Penjumlahan, pengurangan : +, -. Contoh : (A – B) * (C + D) Prioritas pengerjaan soal duatas adalah sebagai berikut :
a. Dalam kurung yang paling kiri : (A – B) b. Dalam kurung yang kedua : (C – D)
c. Perkalian hasil pengurangan dengan hasil penjumlahan. Notasi prefiks dan notasi postfix lebih mudah dikerjakan oleh komputer.
 Prefix adalah keadaan dimana simbol operator diletakkan sebelum dua
operand.
 Postfix adalah keadaan dimana simbol operator diletakkan sesudah dua
Aturan notasi infix, prefiks, dan postfix :
 Notasi Infix :operand operator operand A + B
 Notasi Prefix :operator operand operand + A B (disebut juga Polish Notation – PN)
 Notasi Postfix : operand operand operator (disebut juga Reveser Polish Notation – RPN)
Contoh ke-1 : Infix ke Prefix (A+B) – (C*D)
Cara pengerjaan :
a. Pengerjaan dalam kurung ke-1 : (A+B), prefixnya adalah +AB b. Pengerjaan dalam kurung ke-2 : (C*D), prefixnya adalah *CD
c. Terakhir adalah operator -, +AB - *CD, prefixnya adalah +AB*-CD
Contoh ke-2 : Infix ke Postfix (A+B)-(C*D)
Cara pengerjaan :
a. Pengerjaan dalam kurung ke-1 : (A+B), postfixnya adalah AB+ b. Pengerjaan dalam kurung ke-2 : (C*D), postfixnya adalah CD*
c. Terakhir adalah operator -, AB+ - CD*, postfixnya adalah
AB+CD*-Contoh ke-3 : Prefix ke Infix : +/*ABCD
Cara pengerjaan : mencari operator dimulai dari operand rekanan :
a. Cari operator ke-1 : *, ambil dua operand sebelumnya A dan B, sehingga infixnya adalah (A*B)
b. Cari operator ke-2 : /, ambil dua operand sebelumnya (A*B) dan C, sehingga infixnya adalah ((A*B)/C)
c. Cari operator ke-3 : +, ambil dua operand sebelumnya ((A*B)/C) dan D, sehingga infixnya adalah ((A*B)/C)+D
Contoh ke-4 : Prefix ke Postfix : +/*ABCD
Cara pengerjaan : mencari operator dimulai dari operand rekanan
a. Cari operator ke-1 : *, ambil dua operand sebelumnya A dan B, sehingga postfixnya adalah AB*
b. Cari operator ke-2 : /, ambil dua operand sebelumnya AB* dan C, sehingga postfixnya adalah AB*C/
c. Cari operator ke-3 : +, ambil dua operand sebelumnya AB* C/ dan D, sehingga postfixnya adalah AB*C/D+
Contoh ke-5 : Postfix ke Infix :
ABCD*/-Cara pengerjaan : mencari operator dimulai dari operand terkiri :
a. Cari operator ke-1 : *, ambil dua operand sebelumyna C dan D, sehingga infixnya adalah (C*D)
b. Cari operator ke-2 : /, ambil dua operand sebelumnya B dan (C*D), sehingga infixnya adalah (B/(C*D))
c. Cari operator ke-3 : -, ambil dua operand sebelumnya A dan (B/C*D)), sehingga infixnya adalah A-(B/(C*D))
Contoh ke-6 : Postfix ke Prefix :
ABCD*/-Cara pengerjaan : mencari operator dimulai dari operand terkiri :
a. Cari operator ke-1 : *, ambil dua operand sebelumnya C dan D, sehingga prefixnya adalah *CD
b. Cari operator ke-2 : /, ambil dua operand sebelumnya B dan *CD, sehingga prefixnya adalah /B *CD
c. Cari operator ke-3 : -, ambil dua operand sebelumnya A dan /B *CD, sehingga prefixnya adalah – A/B*CD.
Algoritma Infix ke Postfix Contoh sederhana infix 3 + 2 * 5 stack Postfix
2.12 Aturan Pengerjaan
1. Baca soal dari depan ke belakang
2. Jika soal berupa operand, maka masukkan ke postfix 3. Jika berupa operator, maka :
 jika stack masih kosong, push ke stack
 jika derajat operator soal > derajat operator top of stack  push operator soal ke stack
 selama derajat operator soal <= derajat operator top of stack  pop top of stack dan masukkan kedalam postfix
 setelah semua dilakukan, push operator soal ke stack
 jika sudah semua soal dibaca, pop semua isi stack dan push ke postfix sesuai dengan urutannya.
Contoh lain
 a + b * c – d
o stack (kosong) dan postfix (kosong)
 Scan a o Postfix : a  Scan + o Stack : +  Scan b o Postfix : ab
 Scan *, karena ToS(+)<*, maka add ke stack
o Stack : +*
 Scan c
o Postfix : abc
 Scan -, karena *>-, maka pop stack, dan add ke postfix
o Stack : + o Postfix : abc*
o Karena +>=-, maka pop stack, dan add ke postfix, karena stack kosong, maka push – ke stack
o Stack :
-o Postfix : abc*+
 Scan d
o Postfix : abc*+d
 Karena sudah habis, push ToS Stack ke Postfix
o Postfix :
abc*+d-Penggunaan notasi postfix dalam stack, misal : 2 13 + 5 * = 80
Push 2 pop 14 push 5 pop 5 pop 80
Push 14 pop 2 pop 16
Push 2 push 16
+ 14 * 5
Contoh : ubah ekspresi A+B*C+(D+E)*F ke dalam notasi postfix dengan menggunakan algoritma Dijkstra
Contoh stack
#include <iostream> #define MAXSTACK 100 using namespace std; typedef int itemType; typedef struct { int item[MAXSTACK]; int jml; } Stack; void init(Stack *s) { s->jml=0; }; int kosong(Stack *s) { return (s->jml==0); } int penuh(Stack *s) { return (s->jml==MAXSTACK); }
void isi(itemType x, Stack *s) {
if(penuh(s)) {
cout<<" Maaf data sudah penuh"<<endl;
cout<<"---"<<endl; } else { s->item[s->jml]=x; ++(s->jml); } }
void ambil(Stack *s, itemType *x) {
if(kosong(s)) {
cout<<" Maaf data masih kosong"<<endl;
cout<<"---"<<endl; } else { --(s->jml); *x=s->item[s->jml]; s->item[s->jml]=0;
cout<<" Data "<<*x<<" berhasil diambil"<<endl;
cout<<"---"<<endl; } } void tampil(Stack *s) { if(kosong(s)) {
cout<<" Maaf data masih kosong"<<endl;
cout<<"---"<<endl; } else cout<<endl; for(int i=s->jml-1;i>=0;i--) { cout<<"Data "<<s->item[i]<<endl; } } void hapus(Stack *s) { s->jml=0;
cout<<" Semua data berhasil dihapus"<<endl;
cout<<"---"<<endl; } int main() { int pil; Stack tumpukan; itemType data; init(&tumpukan); do {
cout<<"Selamat datang di Aplikasi stack"<<endl; cout<<"1. PUSH(Memasukan)"<<endl;
cout<<"2. POP(Mengangkat/Memanggil)"<<endl; cout<<"3. Display(Menampilkan)"<<endl;
cout<<"4. Delete(Hapus)"<<endl; cout<<"5. Exit"<<endl;
cout<<"Masukkan pilihan : ";cin>>pil;
cout<<"---"<<endl;
switch(pil) {
case 1:
cout<<"---"<<endl; isi(data,&tumpukan); break; case 2: ambil(&tumpukan,&data); break; case 3: tampil(&tumpukan); break; case 4: hapus(&tumpukan); break; } } while(pil!=5);
cout<<" Terima Kasih"<<endl;
cout<<"---"<<endl; return 0; } Tampil an H asil
2.13 Pengertian Queue
Secara harfiah, queue dapat diartikan sebagai antrian. Queue merupakan kumpulan data dengan penambahan data hanya melalui satu sisi, yaitu bagian belakang (tail) dan penghapusan data hanya melalui sisi depan (head). Berbeda dengan Stack yang bersifat LIFO, maka queue bersifat FIFO (First In First Out), yaitu data yang pertama masuk akan keluar terlebih dahulu dan data yang terakhir masuk akan keluar terakhir. Berikut ini adalah gambaran struktur data queue seperti pada gambar dibawah ini :
Elemen yang pertama kali masuk ke dalam queue disebut elemen depan (front / head of queue), sedangkan elemen yang terakhir kali masuk ke queue disebut dengan elemen belakang (rear / Tagil of queue).
Perbedaan antara stack dan queue terdapat pada aturan penambahan dan penghapusan elemen. Pada stack, operasi penambahan dan penghapusan elemen
dilakukan di satu ujung. Elemen yang terakhir kali dimasukkan akan berada paling dekan dengan ujung atau dianggap paling atas sehingga pada operasi penghapusan, elemen teratas tersebut akan dihapus paling awal, sifat demikian dikenal dengan LIFO. Pada queue, operasi tersebut dilakukan melalui salah satu ujunh, menempati posisi belakang elemen-elemen yang sudah masuk sebelumnya atau menjadi elemen paling belakang. Sedangkan penghapusan elemen dilakukan di ujung yang berbeda, yaitu pada posisi elemen yang masuk paling awal atau elemen terdepan. Sifat yang demikian dikenal dengan FIFO.
Walaupun berbeda implementasinya, struktur data queue setidaknya harus memiliki operasi-operasi sebagai berikut :
Inisialisasi menginisialisasi antrian
 EnQueue : Memasukkan data ke dalam antrian
 DeQueue : Mengeluarkan data terdepan dari antrian
 Clear : Menghapus seluruh antrian
 IsEmpty : memeriksa apakah antrian kosong
 IsFull : Memeriksa apakah antrian penuh
2.14 Implementasi Queue Dengan Linear Array
Berikut ini diberikan deklarasi kelas Queue Linear sebagai implementasi dari queue menggunakan linear array. Dalam praktiknya, anda dapat menggantinya sesuai dengan kebutuhan anda. Data diakses dengan field data, sedangkan indeks item pertama dan terakhir disimpan dalam field Head dan Tail. Konstruktor akan menginisialisasikan nilai Head dan Tail dengan -1 untuk MAX_QUEUE yang ditunjuk oleh data. Destruktor akan mengosongkan antrikan kembali dan mendealokasikan memori yang digunakan oleh antrian.
2.15 Operasi-Operasi Queue Dengan Linear Array
2.15.1 Pendeklarasian Sebuah Queue
Setiap queue memiliki elemen-elemen (field) berupa posisi depan, posisi belakang, elemen antrian, dan maksimal elemennya.
2.15.2 Inisialisasi Queue
Inisialisasi queue adalah proses pemberian nilai 0 untuk field depan dan belakang dari queue dan juga pemberian nilai max ke maks_queue yang menunjukkan banyaknya maksimal data dalam queue. Karena dalam bahasa C++, elemen sebuah array dimulai dari 0 bukan -1 sehingga ketika
ada proses penambahan elemen (enqueue) akan bernilai 0 sehingga elemen tersebut akan disimpan dalam elemen antrian pada posisi 0.
2.15.3 Fungsi IsEmpty
Fungsi kosong (IsEmpty) digunakan untuk memeriksa apakah keadaan queue tidak memiliki elemen. Fungsi kosong didapatkan dengan memeriksa field belakang dari queue. Jika field belakang bernilai 0, maka berarti queue kosong dan jua tidak 0, maka berarti queue mempunyai elemen. Implementasi dalam bahasa C++ agak berbeda karena elemen array dimulai dari 0 sehingga pemeriksaan nilai belakang dilakukan dengan membandingkan dengan nilai -1. Jika nilai belakang berniolai -1 maka queue kosong (true) dan jika lebih dari -1 berarti queue tidak kosong (false).
2.15.4 Fungsi IsFull
Fungsi IsFull berguna untuk memeriksa apakah suatu queue telah penuh. Fungsi ini diperlukan ketika proses enqueue. Fungsi ini akan bernilai benar (true) jika field belakang sama dengan nilai maks_queue jika tidak sama, maka dapat dipastikan bahwa queue belum penuh. Dalam bahasa C++, perbandingan yang dilakukan adalah bukan dengan maks_queue tetapi dengan nilai maks_queue-1 karena elemen array dimulai dari posisi 0.
2.15.5 Fungsi EnQueue
Proses EnQueue adalah proses untuk penambahan di posisi belakang. Penambahan ini dilakukan jika kondisi queue tidak penuh. Jika keadaan masih kosong, maka field depan dan belakang bernilai 1, tetapi jika sudah mempunyai elemen, maka nilai belakang harus bertambah 1. Kemudian data baru disimpan di array pada posisi belakang. Implementasi dalam C++ harus melakukan penyesuaian karena elemen array dimulai dari 0, sehingga ketika queue masih kosong, pemberian nilai depan dan belakang adalah 0 bukan 1.
2.15.6 Fungsi DeQueue
Operasi DeQueue adalah proses pengambilan elemen queue. Tentunya elemen yang diambil selalu dari elemen pertama(1). Setelah elemen pertama diambil, maka akan diperlukan proses pergeser ah elemen data setelah elemen diambil, maka akan diperlukan proses pergeseran elemen data setelah elemen data yang diambil (dari posisi ke-2 sampai posisi paling belakang), dan kemudian posisi belakang akan dikurangi 1 karena ada data yang diambil. Implementasi dalam bahasa C++ dilakukan dengan pengambilan elemen pada posisi 0.
Contoh Queue dengan Linear Array
#include <iostream> #define max 8 using namespace std; typedef struct{ int data[max]; int head; int tail; }Queue; Queue antrian;
void init(){ antrian.head = -1; antrian.tail = -1; } int kosong(){ if(antrian.tail==-1) {
return 1; //data kosong }
else {
return 0; //data berisi }
}
int penuh(){
if(antrian.tail==max-1) {
return 1; //data penuh }
else{
return 0; //data berisi }
}
void masuk(){ int data;
cout <<"Masukkan bilangan = "; cin >>data; if(penuh()==0) { antrian.tail++; antrian.data[antrian.tail]=data; cout<<"\n"<<antrian.data[antrian.tail] <<" masuk "; } else{
cout <<"Data penuh"; } } int keluar(){ int i; if(kosong()==1){ cout<<"Kosong cuy"; }else{ int x=antrian.data[antrian.head+1]; for(i=antrian.head;i<antrian.tail;i++){ antrian.data[i]=antrian.data[i+1]; } antrian.tail--;
cout <<x <<" berhasil dikeluarkan "; return x;
} }
void clear(){ init();
cout <<"Data telah dikosongkan"; }
if(kosong()==0) { for(int i=antrian.head+1;i<=antrian.tail;i++){ cout <<antrian.data[i]<<" "; } } else{
cout <<"Data masih kosong"; } } int main(){ int pil; init(); cout<<"*---*"<<endl; cout<<"* Q u e u e ( A N T R I A N ) *"<<endl; cout<<"*---*"<<endl; do{ cout<<"\n"; cout<<"\n********************************"; cout<<"\n1. Masukkan Data";
cout<<"\n2. Keluarkan Data"; cout<<"\n3. Kosong Data"; cout<<"\n4. Cetak Data";
cout<<"\n\nSilahkan Masukan Pilihan Anda : ";cin>>pil; cout<<"\n"; switch (pil){ case 1: { masuk(); break; } case 2: { keluar(); break; } case 3: { clear(); break; } case 4: { tampil(); break; } default : {
cout<<"\n Maaf, Tidak ada dalam pilihan"; }
} }
while(pil>=1 && pil<= 4); return 0;
Tampil an H asil
2.16 Implementasi Queue dengan Circular Array
Ala satu variasi array adalah array yang bentuknya melingkar (circual array). Artinya array dapat diakses mulai dari sembarang indeks(indeks awal) karah indeks terakhir(maksimum indeks), lalu memutar ke indeks pertama hingga kembali ke indeks awal. Circular array adalah array yang dibuat seakan-akan merupakan sebuah lingkaran dengan titik awal dan titik akhir saling bersebelahan jika array tersebut masih kosong. Jumlah data yang dapat ditampung oleh array ini adalah besarnya ukuran array dikurangi 1. Misalnya besar array adalah 8, maka jumlah data yang dapat ditampung adalah 7.
Dengan circular array, meskipun posisi terakhir telah dipakai, elemen baru tetap dapat ditambahkan pada posisi pertama jika posisi pertama dalam keadaan kosong. Jika akhir = MAX dan awal = 1, nilai head dan Tagil mencapai maksimum, maka akan dikembalikan ke posisi awal. Operasi-operasi yang terdapat pada circular array tidak jauh berbeda dengan operasi pada linear array.
Aturan-aturan dalam queue yang menggunakan circular array adalah :
1. Proses penghapusan dilakukan dengan cara nilai depan(front) ditambah 1 : depan += 1
2. Proses penambahan elemen sama dengan linear array yaitu nilai belakang ditambah 1 : belakang += 1
3. Jika depan = maks dan ada elemen yang akan dihapus, maka nilai depan = 1
4. Jika belakang = maks dan depan tidak 1, maka jika ada elemen yang akan ditambahkan, nilai belakang = 1
5. Jika hanya tinggal 1 elemen di queue (depan = belakang), dan akan dihapus maka depan diisi 0 dan belakang diisi dengan 0 (queue kosong)
Contoh :
3.4.1 Pendeklarasian Queue
Setiapqueue memiliki elemen-elemen(field) berupa posisi depan, posisi belakang, elemen antrian, dan elemen maksimal.
3.4.2 Inisialisasi Queue
Inisialisasi queue adalah proses pemberian nilai 0 untuk field depan dan belakang dari queue dan juga pemberian nilai maks ke maks_queue yang menunjukan banyaknya maksimal data dalam queue. Karena dalam bahasa C++ elemen sebuah array dimulai dengan 0 maka proses inisialisasi nilai depan dan belakang bukan 0 tetapi -1 sehingga ketika ada proses penambahan elemen (enqueue) akan bernilai 0 sehingga elemen tersebut
akan disimpan dalam elemen antrian pada posisi 0.
3.4.3 Fungsi IsEmpty
Suatu queue yang menggunakan circular array dapat dikatakan kosong jika nilai yang menunjuk posisi depan atau belakang mempunyai nilai 0.
Implementasi dalam bahasa C++, perbandingan posisi depan atau belakang dilakukan bukan dengan angka 0 tetapi angka -1 karena angka 0 menunjukan elemen pertama dari array.
3.4.4 Fungsi IsFull
Suatu queue akan disebut penuh jika terjadi 2 hal yaitu jika nilai depan mempunyai nilai 1 dan posisi belakang sama dengan maks_queue atau jika posisi depan sama dengan posisi belakang +1. Jika salah satu dari 2 hal tersebut terjadi maka fungsi penuh mempunyai nilai true dan jika tidak terjadi 2 hal tersebut maka fungsi bernilai false. Implementasi dalam bahasa C++ agar beda karena posisi awal array bukan 1 tapi 0 dan posisi terakhir data adalah maks_queue-1 bukan maks_queue.
3.4.5 Fungsi EnQueue
Proses enqueue data hanya bisa dilakukan jika queue tidak kosong. Ada beberapa hal yang harus diperhatikan ketika akan melakukan enqueue pada
circular array, diantaranya adalah :
1. Kondisi ketika queue masih kosong. Jika ini terjadi, maka posisi depan dan belakang bernilai 0.
2. Ketika ketika nilai belakang sama dengan maks_queue, maka posisi belakang adalah 0. Ini terjadi ketika posisi depan lebih besar dari 0
(pernah ada dequeue).
3. Ketika nilai belakang masih lebih kecil dari maks_queue maka posisi belakang ditambah 1 : belakang+=1;
Dari ketentuan-ketentuan di atas dapat diimplementasikan dalam bahasa C++ dengan mengganti beberapa hal yaitu posisi perbandingan / pengisian dengan nilai 0 diganti dengan perbandingan / pengisian dengan nilai -1 dan perbandingan dengan nilai maks_queue diganti dengan maks_queue-1 Itu disebabkan karena dalam bahasa C++ array dimulai dari 0.
3.4.6 Fungsi DeQueue
Proses dequeue hanya bisa dilakukan jika queue dalam keadaan tidak kosong. Ada beberapa kondisi yang harus diperhatikan ketika dequeue elemen queue yaitu :
Kondisi ketika posisi depan sama dengan posisi belakang (queue hanya memiliki 1 elemen) maka nilai depan dan belakang diisi dengan 0 (queue kosong).
Jika posisi depan sama dengan posisi maks_queue maka posisi depan berpindah ke 1.
Selain itu, posisi depan ditambah dengan 1 : depan=depan+1 Ketika kita mengimplementasikannya dalam bahasa C++, maka ada beberapa hal yang harus diganti adalah semua pengisian/perbandingan dengan angka 1 diganti dengan 0 (karena elemen array dalam bahasa C++ adalah 0), serta ketika ada perbandingan/pengisian dengan nilai 0 diganti dengan -1 dan perbandingan/pengisian dengan nilai maks_queue diganti dengan maks_queue-1.
Contoh : Program Circular Array #include <iostream> using namespace std; typedef struct{ int data[5]; int head; int tail; }Queue; Queue antri; typedef struct { int baru; }struk; struk variabel; void input(){ if(antri.tail== 5-1) { cout<<"Antrian Penuh"; } else {
cout<<"Data yang akan di Push = ";cin>>variabel.baru; antri.tail++;
antri.data[antri.tail]=variabel.baru;
cout<<"Head = "<<antri.head<<" Tail = "<<antri.tail; } } void out(){ if(antri.tail < antri.head) { cout<<"Antrian Kosong"; } else { //koreksi
cout<<"Data yang akan di keluar = "<<antri.data[antri.head]<<endl;
antri.head = antri.head+1;
cout<<"Head = "<<antri.head<<" Tail = "<<antri.tail; } } void cetak(){ if(antri.tail==-1) { cout<<"Antrian Kosong"; } else{ cout<<endl;
cout<<"Data dalam antrian adalah : "<<endl<<endl; //koreksi for(int i=antri.head;i<=antri.tail;i++){ cout<<antri.data[i]<<" "; } } } int main(){
int pil, baru, i; //koreksi
antri.tail=-1; cout<<"====================================="<<endl; cout<<"= Q u e u e ( A N T R I A N ) ="<<endl; cout<<"====================================="<<endl; do{ cout<<endl; cout<<"*************************************"<<endl; cout<<"1. Masukkan Data"<<endl;
cout<<"2. Keluarkan Data"<<endl; cout<<"3. Cetak Data"<<endl;
cout<<"Silahkan Masukan Pilihan Anda : ";cin>>pil; cout<<endl; switch (pil){ case 1: { input(); break; } case 2: { out(); break; } case 3: { cetak(); break; } default : { cout<<"---"<<endl;
cout<<" Maaf, Tidak ada dalam pilihan "<<endl; cout<<"---"<<endl; } } }
while(pil>=1 && pil<= 3); }
Tugas !
Buatlah program stack dengan syarat :
a) User memasukkan data berupa NIM dan Nama. b) User dapat mengeluarkan data.
c) Kosongkan data. d) Cetak data
BAB III
SORTING
3.1 Pendahuluan
 Pengurutan data dalam struktur data sangat penting terutama untuk data yang bertipe data numerik ataupun karakter
 Pengurutan dapat dilakukan secara ascending (urut naik) maupun descending (urut turun)
 Pengurutan (sorting) adalah proses pengurutan data yang sebelumnya disusun secara acak sehingga secara teratur menurut aturan tertentu. Contoh :
Data Acak : 9 1 0 5 78 31 55 10 Ascending : 0 1 5 9 10 31 55 78 Descending : 78 55 31 10 9 5 1 0
3.2 Deklarasi Array Untuk Sorting
Deklrasi secara global :
Inti data[100];
Inti n; //untuk jumlah data
Prosedur Tukar 2 Buah Data : void tukar { int tmp = data[a]; data[a] = data[b]; data[b] = tmp; }
3.3 Insertion Sort
1. Mirip dengan cara orang mengurutkan kartu, selembar demi selembar kartu diambil dan disisipkan ke tempat yang seharusnya.
2. Pengurutan dimulai dari data ke-2 sampai data terakhir, jika ditemukan data yang lebih kecil, maka akan ditempatkan pada posisi yang seharusnya.
3. Pada penyisipan elemen, maka elemen-elemen lain akan bergeser ke belakang.
Contoh : Sour ce CodeInsertion Sort #include <iostream>
using namespace std; int data[10],data2[10]; int n;
{
int t;
t = data[b]; data[b] = data[a]; data[a] = t; }
void Input() {
cout<<"Masukkan jumlah data = ";cin>>n;
cout<<"--- "<<endl; for(int i=0;i<n;i++)
{
cout<<"Masukkan data ke-"<<(i+1)<<" = ";cin>>data[i]; data2[i] = data[i]; } cout<<endl; } void Tampil() { for(int i=0;i<n;i++) { cout<<data[i]<<" "; } cout<<endl; } void insertion_sort() { int temp,i,j; for(i=1;i<n;i++) { temp = data[i]; j = i -1; while(data[j]>temp && j>=0) { data[j+1] = data[j]; j--; }
data[j+1] = temp; Tampil(); } cout<<endl; } main() { cout<<"*---*"<<endl;
cout<<"* Selamat datang di aplikasi *"<<endl; cout<<"* Insertion Sort *"<<endl;
cout<<"*---*"<<endl; Input();
cout<<"Proses Insertion Sort,,,,,,,"<<endl;
cout<<"--- "<<endl; Tampil();
insertion_sort();
cout<<"--- "<<endl; cout<<" TERIMA KASIH "<<endl; cout<<"--- "<<endl; }
Tampil an H asil
3.4 Quicksort
Metode sorting dengan quicksort cukup sulit dipahami, namun metode ini merupakan metode sorting tercepat yang ada dengan kompleksitas n logn. Metode ini menggunakan paradigma devide & conquer, sehingga dalam prosesnya metode ini membagi array menjadi 2 bagian untuk selanjutnya diproses kembali secara rekursif dengan memanggil dirinya sendiri.
Di dalam metode ini dikenal beberapa istilah, yaitu : 1. Pivot
sembarang elemen array yang digunakan sebagai batas. Pivot ini dapat dipilih secara random atau dengan memilih elemen yang berada di tengah array.
2. Partisi
Hasil pembagian array menjadi 2 sub-array melalui proses pemartisian.
Berikut Ilustrasi Algoritma Quicksort.
ContohSour ce Code Quicksort
#include <iostream> using namespace std; int data[10], data2[10]; int n;
void tukar(int a, int b) { int t; t = data[b]; data[b] = data[a]; data[a] = t; } void Input() {
cout<<"Masukkan jumlah data = "; cin>>n;
cout<<"--- "<<endl; for(int i=0;i<n;i++)
{
cout<<"Masukkan data ke-"<<(i+1)<<" = "; cin>>data[i];
} cout<<endl; } void Tampil() { for(int i=0;i<n;i++) { cout<<data[i]<<" "; } cout<<endl; }
void QuickSort(int L, int R) //the best sort i've ever had :) { int i, j; int mid; i = L; j = R; mid = data[(L+R) / 2]; do {
while (data[i] < mid) i++; while (data[j] > mid) j--; if (i <= j) { tukar(i,j); i++; j--; }; Tampil(); } while (i < j); if (L < j) QuickSort(L, j); if (i < R) QuickSort(i, R); } main() { cout<<"*--- *"<<endl; cout<<"* Selamat datang di aplikasi *"<<endl; cout<<"* Quick Sort *"<<endl; cout<<"*--- *"<<endl; Input();
cout<<"Proses Quick Sort,,,,,,,"<<endl;
cout<<"--- "<<endl; Tampil();
QuickSort(0,n-1);
cout<<"--- "<<endl; cout<<" TERIMA KASIH "<<endl; cout<<"--- "<<endl; }
Tampil an H asil
Tugas !
1. Buatlah 2 buah program pengurutan dengan menggunakan metode insertion sort dan quick sort dengan jumlah data sebanyak N dan bilangan acak berupa T
Input :
Nilai N dan T sejumlah nilai N Output :
e) Urutan bilangan secara ascending f) Urutan bilangan secara descending
2. buatlah program untuk mengurutkan data mahasiswa (NIM, Nama, Jenis Kelamin, Tanggal Lahir). Program harus bisa melayani pengurutan secara ascending atau descending, dan pengurutan bisa dipilih berdasarkan nama atau NIM.
3. Buatlah program sorting dengan menggunakan metode insertion sort. User akan diminta menginput 10 bilangan yang kemudian akan diurutkan. Sediakan pula fungsi untuk mencari posisi bilangan (bilangan yang akan dicari ada pada daftar bilangan yang telah diurutkan, beritahukan pada urutan kepada bilangan tersebut).
BAB IV
SEARCHING
4.1 Pengertian
Dalam kehidupan sehari-hari sebenarnya kita sering melakukan pencarian data. Sebagai contoh, jika kita menggunakan kamus untuk mencari kata-kata dalam Bahasa Ingrris yang belum kita ketahui terjemahannya dalam Bahasa Indonesia. Contoh lain yaitu ketika kita menggunakan buku telepon untuk mencari nomor telepon teman, dan masih banyak contoh lainnya. Pencarian juga sering disebut dengan Table Look-Up atau Storage & Retrieval Information yang mana ini adalah suatu proses untuk mengumpulkan sejumlah informasi di dalam pengingat komputer dan kemudian mencari kembali informasi yang diperlukan
secepat mungkin.
Algoritma pencarian (searching algorithm) adalah algoritma yang menerima sebuah argumen kunci dan dengan langkah-langkah tertentu akan mencari rekaman dengan kunci tersebut. Setelah proses pencarian dilaksanakan, akan diperoleh salah satu dari dua kemungkinan, yaitu data yang dicari berhasil ditemukan (successful) atau data yang kita cari tersebut tidak berhasil ditemukan (unsuccessful).
Metode pencarian data dapat dilakukan dengan dua cara, yaitu pencarian data bagian dalam (internal searching) dan pencarian data bagian luar (external searching). Pada internal searching, semua rekaman yang diketahui berada dalam pengingat komputer. Sedangkan pada external searching tidak semua rekaman yang diketahui berada dalam pengingat komputer, tetapi ada sejumla rekaman yang tersimpan dalam penyimpanan luar. Misalnya pita atau cakram magnetis. Selain itu metode pencarian data juga dapat dikelompokkan menjadi pencarian statis (static searching) dan pencarian dinamis (dynamic searching). Pada pencarian statis, banyaknya rekaman data yang diketahui dianggap tetap. Pada pencarian dinamis, banyaknya rekaman data yang diketahui bisa berubah-ubah
yang mana disebabkan oleh penambahan atau penghapusan suatu rekaman.
Ada dua macam teknik pencarian yaitupencarian sekuensialdanpencarian biner. Perbedaan dari dua teknik ini terletak pada keadaan data. Pencarian sekuensial digunakan apabila data dalam keadaan acak atau tidak terurut (contoh: sequential search). Sebaliknya, pencarian biner digunakan pada data yang sudah dalam keadaan urut (contoh: Binary serach dan interpolation search).
4.2 Sequential Searching (Pencarian Berurutan)
Pencarian berurutan sering disebut pencarian linear merupakan metode pencarian yang paling sederhana. Pencarian berurutan menggunakan prinsip sebagai berikut : data yang ada dibandingkan satu per satu secara berurutan dengan yang dicari sampai data tersebut ditemukan atau tidak ditemukan.
Pada dasarnya, pencarian ini hanya melakukan pengulangan dari 1 sampai dengan jumlah data. Pada setiap pengulangan, dibandingkan data ke-i dengan yang dicari. Apabila sama, berarti data telah ditemukan. Sebaliknya apabila sampai akhir pengulangan tidak ada data yang sama, berarti data tidak ada. Pada kasus yang paling buruk, untuk N elemen data harus dilakukan pencarian sebanyak N kali pula.
Algoritma pencarian berurutan dapat dituliskan sebagai berikut : 1. i ← 0
2. ditemukan← false
3. selama (tidak ditemukan) dan (i <= N) kerjakan baris 4
4. jika (data[i] = x) maka ditemukan← tua, jika tidak i ← i + 1
5. jika (ditemukan) maka i adalah indeks dari data yang dicari, jika tidak maka data tidak ditemukan.
Konsep : membandingkan setiap setiap elemen larik satu per satu secara urut (beruntun), mulai dari elemen pertama sampai dengan elemen yang terakhir. Ada 2 macam pencarian beruntun,yaitu pencarian pada array yang sudahterurut, dan pencarian pada array yangbelum terurut.
Contoh(1) :
Contoh (2) :
4.3 Binary Search
Salah satu syarat agar pencarian biner dapat dilakukan adalah data sudah dalam keadaan urut. Dengan kata lain, apabila data belum dalam keadaan urut, pencarian biner tidak dapat dilakukan. Dalam kehidupan sehari-hari, sebenarnya kita juga sering menggunakan pencarian biner. Misaln ya saat ingin mencari suatu kata dalam kamus Prinsip dari pencarian biner dapat dijelaskan s ebagai berikut : 1. mula-mula diambil posisi awal 0 dan posisi akhir = N-1, kemudian cari
posisi data tengah dengan rumus (posisi awal + posisi akhir) / 2. Kemudian data yang dicari dibandingkan dengan data tengah.
2. Jika lebih kecil, proses dilakukan kembali tetapi posisi akhir dianggap sama dengan posisi tengah -1
3. Jika lebih besar, proses dilakukan kembali tetapi posisi awal dianggap sama dengan posisi tengah + 1
Demikian seterusnya sampai data tengah sama dengan yang dicari.Untuk lebih jelasnya perhatikan contoh berikut :
Misalnya ingin mencari data 17 pada sekumpulan data berikut :
Mula-mula dicari data tengah, dengan rumus (0 + 9) / 2 = 4. Berarti data tengah adalah data ke-4, yaitu 15. Data yang dicari, yaitu 17, dibandingkan dengan data tengah ini. Karena 17 > 15, berarti proses dilanjutkan tetapi kali ini posisi awal dianggap sama dengan posisi tengah + 1 atau 5.
Data tengah yang baru didapat dengan rumus (5 + 9) / 2 = 7. Berarti data tengah yang baru adalah data ke-7, yaitu 23. Data yang dicari yaitu 17 dibandingkan dengan data tenah ini. Karena 17 < 23, berarti proses dilanjukkan tetapi kali ini posisi akhir dianggap sama dengan posisi tengah – 1 atau 6.
Data tengah yang baru didapat dengan rumus (5 + 6) / 2 = 5. Berarti data tengah yang baru adalah data ke-5, yaitu 17. data yang dicari dibandingkan
dengan data tengah ini dan ternyata sama. Jadi data ditemukan pada indeks ke-5. Pencarian biner ini akan berakhir jika data ditemukan atau posisi awal lebih besar daripada posisi akhir. Jika posisi sudah lebih besar daripada posisi akhir berarti data tidak ditemukan.
Untuk lebih jelasnya perhatikan contoh pencarian data 16 pada data diatas. Prosesnya hampir sama dengan pencarian data 17. Tetapi setelah posisi awal 5 dan posisi akhir 6, data tidak ditemukan dan 16 < 17, maka posisi akhir menjadi posisi tengah – 1 atau = 4 sedangkan posisi awal = 5.
Disini dapat dilihat bahwa posisi awal lebih besar daripada posisi akhir, yang artinya data tidak ditemukan. Algoritma pencarian biner dapat dituliskan sebagai berikut :
1. L ← 0 2. R ← N – 1
3. ditemukan ← false
4. selama (L <= R) dan (tidak ditemukan) kerjakan baris 5 sampai dengan 8 5. m ← (L + R) / 2
6. jika (data[m] = x) maka ditemukan ← true 7. jika (x < data[m]) maka R ← m – 1
8. jika (x > data[m]) maka L ← m + 1
9. jika (ditemukan) maka m adalah indeks dari data yang dicari, jika tidak, maka dapat dipastikan bahwa data tidak ditemukan.
Tampilan H asil
4.4 Interpolation Search
Teknik ini dilakukan pada data yang sudah terurut berdasarkan kunci tertentu. Teknik searching ini dilakukan dengan perkiraan letak data. Contoh ilustrasi : jika kita hendak mencari suatu kata dalam buku telepon, misal yang berawalan dengan huruf J, maka kita tidak akan mencarinya dari awal buku, tetapi kita langsung membukanya pada 1/3 atau 1/4 dari tebal buku tersebut.
Rumus posisi relatif kunci pencarian dihitung dengan rumus :
- jika data[posisi] > data yang dicari, high = pos – 1 - jika data[posisi] < data yang dicari, low = pos + 1
contoh scipt : #include <iostream> #include <cmath> using namespace std; main() { int data[8] = {10,12,93,44,85,36,57,68}; int low, high, cari, pos, tanda = 0; float pos1;
int N = 8; low = 0;
high = N - 1;
cout << "Datanya Yaitu : " << endl; for (int x = 0; x <= 7; x++)
{
cout << "\t" << data[x] << endl; }
cout << "=================================" << endl; cout << "Masukkan Data Yang Ingin Dicari : ";
cin >> cari; do
{
pos1 = (cari-data[low])/(data[high]-data[low])*(high-low)+low;
pos = floor(pos1); //pembulatan nilai kebawah if (data[pos] == cari) { tanda = 1; break; } if (data[pos] > cari) { high = pos - 1; } else if (data[pos]) { low = pos + 1; } }
while (cari >= data[low] && cari <= data[high]); if (tanda == 1)
{
cout << ":: Data Ditemukan ::" << endl; }
else {
cout << ":: Data Tidak Ditemukan :: " << endl; }
}
Tugas :
1. Buatlah program searching, dengan ketentuan :
 Data yang tersedia adalah inputan user
 Banyak data yang di inputkan, ditentukan oleh user juga
 Setelah pencarian jika data tersebut ditemukan, maka harus
menyebutkan indeks keberapa data tersebut
BAB V
LINKED LIST
5.1 Pengertian Lindked List
 Linked List adalah salah satu bentuk struktur data yang berisi kumpulan data (node) yang tersusun secara sekuensial, saling sambung-menyambung dan dinamis
 Linked List sering disebut juga sebagai Senarai Berantai
 Linked List saling terhubung dengan bantuan variabel pointer
 Asing-masing data dalam Linked List disebut dengan node (simpul) yang menempati alokasi memorat secara dinamis dan biasanya berupa struct yang terdiri dari beberapa field.
5.2 Ilustrasi Linked List
 Single Linked List
1. Contoh ilustrasi pada kehidupan nyata tentang hubungan pertemanan
2. Contoh ilustrasi di komputer
 Double Linked List 1.
5.4 Single Linked List
 Single : artinya field pointer-nya hanya satu buah saja dan satu arah. Serta pada akhir node, pointernya menunjuk NULL
 Linked List :artinya node-node tersebut saling terhubung antara satu dengan yang lain
 Setiap node pada linked lis mempunyai field yang berisi pointer ke node berikutnya, dan juga memiliki field yang berisi data
 Node terakhir akan menunjuk ke NULL yang akan digunakan sebagai kondisi berhenti pada saat pembacaam isi linked lis
5.5 Jenis Single List
1. Linked List Dengan Head
5.6 Deklarasi Single Linked List
 Deklarasi NODEPenjelasan
o Pembuatan struct bernama TNode yang berisi 2 field, yaitu field data bertipe integer dan field next yang bertipe pointer dari TNode. Setelah itu membuat variabel yang bernama node yang digunakan kunci untuk mengakses struct TNode.
o Setelah pembuatan struct, buat variabel head yang bertipe pointer dari TNode yang berguna sebagai kepala linked list.
 Pembuatan NODE baru
Penjelasan :
Keyword new gunanya untuk mempersiapkan sebuah node baru beserta alokasi memorinya, kemudian node tersebut diisi data dan poiner
nextnya ditunjuk ke NULL.
5.6.1 Single Linked List Menggunakan Head
Head akan selalu menunjuk pada node pertama
 Ilustrasi penambahan dari depan
1. Lis masih kosong (head == NULL) NULL
Head
3. Masukkan data lagi dari depan, misal 21
Contoh program linked list penambahan dari depan
#include <iostream> using namespace std; struct TNode{ int data; TNode *next; }; TNode *head; void init() { head=NULL; } int cekkosong() { if(head==NULL) { return 0; } else { return 1; } }
void isidepan(int databaru) {
TNode *baru; baru=new TNode;
baru->next=NULL; if (cekkosong==0) { head=baru; head->next=NULL; } else { baru->next=head; head=baru; }
cout<<"Penambahan Data Berhasil"<<endl; }
main() {
int pil, databaru; do
{
cout<<"Menu Pilihan Single Linked List dengan Head"<<endl;
cout<<"1. Insert Data dari Depan"<<endl; cout<<"2. Exit"<<endl;
cout<<"Masukkan Pilihan Anda = "; cin>>pil; switch (pil) { case 1: cout<<"Masukkan Data = "; cin>>databaru; isidepan(databaru); break; } } while(pil!=2); }
 Ilustrasi penambahan dari belakang 1. List masih kosong (Head == NULL)
NULL
Head
2. Masukkan data baru, misalkan 28
4. Masukkan data lagi dari belakang, misal 15
Contoh penambahan dari belakang : #include <iostream>
using namespace std; struct TNode
{
int data; TNode *next; }; TNode *head; void init() { head=NULL; } int cekkosong() { if(head==NULL) { return 0; } else {
return 1; }
}
void isibelakang(int databaru) {
TNode *baru; TNode *bantu; baru=new TNode; baru->data=databaru; baru->next=NULL; if(cekkosong()==0) { head=baru; head->next=NULL; } else { bantu=head; while (bantu->next!=NULL) { bantu=bantu->next; } bantu->next=baru; }
cout<<"Penambahan Data Berhasil"<<endl; }
main() {
int pil, databaru; do
{
cout<<"Menu Pilihan Single Linked List dengan Head "<<endl;
cout<<"1. Insert Data dari Belakang"<<endl; cout<<"2. Exit"<<endl;
cout<<"Masukkan Pilihan Anda = "; cin>>pil; switch (pil) { case 1: cout<<"Masukkan Data = "; cin>>databaru; isibelakang(databaru); break; } } while(pil!=2); }
Tampil an H asil
 Menampilkan isi linked list
void tampil() { TNode *bantu; bantu=head; if (cekkosong==0) {
cout<<"Data Masih Kosong"; }
else
if(bantu==NULL) {
cout<<"Data Masih Kosong"<<endl; } else { while (bantu!=NULL) { cout<<bantu->data<<endl; bantu=bantu->next; } } } Penjelasan :
 Function di atas digunakan untuk menampilkan semua isi list, dimana linked list ditelusuri satu-persatu dari awal node sampai akhir node. Penelusuran ini dilakukan dengan menggunakan suatu pointer bantu, karena pada prinsipnya pointer head yang menjadi tanda awal list tidak boleh berubah
atau berganti posisi
 Penelusuran dilakaukan terus sampai node terakhir ditemukan menunjuk ke nilai NULL. jika tidak null, maka node bantu akan berpindah ke node selanjutnya dan membaca isi datanya dengan menggunakan field next sehingga dapat saling berkait.
 Menghapus data dari depan void hapusDepan () { TNode *hapus; int d; if (cekkosong()==0) { if(head->next != NULL) { hapus = head; d = hapus->data; head = head->next; delete hapus; } else { d = head->data; head = NULL; } cout<<d<<" terhapus\n"; } else cout<<"Masih kosong\n"; } Penjelasan :
 Function diatas akan menghapus data terdepan (pertama) yang ditunjuk oleh head pada linked list
 Penghapusan node tidak boleh dilakukan jika keadaan node sedang dibujuk oleh pointer
 Sebelum data terdepan dihapus, head harus ditunjukkan ke node sesudahnya terlebih dahulu agar list tidak putus, sehingga node setelah head lama akan menjadi head baru (data terdepan yang baru)
 Jika head masih NULL, maka berarti data masih kosong.
void hapusBelakang() { TNode *hapus,*bantu; int d; if (cekkosong()==0) { if(head->next != NULL) { bantu = head; while(bantu->next->next!=NULL) { bantu = bantu->next; } hapus = bantu->next; d = hapus->data; bantu->next = NULL; delete hapus; } else { d = head->data; head = NULL; } cout<<d<<" terhapus\n"; } else cout<<"Masih kosong\n"; } Penjelasan :
 Membutuhkan pointer bantu dan hapus.
 Pointer hapus digunakan untuk menunjuk node yang akan dihapus, dan pointer bantu digunakan untuk menunjuk node sebelum node yang dihapus yang kemudioan selanjutnya akan menjadi node terakhir.
 Pointer bantu akan digunakan untuk menunjuk ke nilai NULL.
 Pointer bantu akan selalu bergerak sampai sebelum node yang akan dihapus, baru kemudian pointer hapus diletakkan setelah pointer bantu. Setelah itu pointer hapus akan dihapus, pointe bantu akan menunjuk ke NULL.
5.6.2 Single Linked List Menggunakan Head dan Tail
 Dibutuhkan dua buah variabel pointer yaitu head dan Tagil
 Head akan selalu menunjuk pada node pertama, sedangkan Tagil akan selalu menunjuk pada node terakhir
 Inisialisasi linked list TNode *head, *tail;  Fungsi inisialisasi linked list
void init() {
head = NULL; tail = NULL; }
 Fungsi untuk mengetahui kosong atau tidaknya suatu linked list int cekkosong() { if (tail == nail) { return 0; } else { return 1; } }
 Penambahan data dari depan dengan head dan tail 1. List masih kosong (head = tail = NULL)
3.
3. Masukkan data lagi dari depan, misal 15Masukkan data lagi dari depan, misal 15
Script penambahan data dari depan dengan head dan tail : Script penambahan data dari depan dengan head dan tail :
#include <iostream> #include <iostream> using namespace std; using namespace std; struct TNode struct TNode { {
int data; TNode *next; int data; TNode *next; };
};
TNode *head, *tail; TNode *head, *tail; void init() void init() { { head=NULL; head=NULL; tail=NULL; tail=NULL; } } int cekkosong() int cekkosong() { { if(tail==NULL) if(tail==NULL) { { return 0; return 0; } } else else { { return 1; return 1; } } } }
void insertDepan(int databaru) void insertDepan(int databaru) {
{
TNode *baru; TNode *baru;
baru = new TNode; baru = new TNode;
baru->data = databaru; baru->data = databaru; baru->next = NULL; baru->next = NULL; if(cekkosong()==0) if(cekkosong()==0) { { head=tail=baru; head=tail=baru; tail->next=NULL; tail->next=NULL; } } else else { { baru->next = head; baru->next = head; head = baru; head = baru; } } cout<<"Data masuk"<<endl; cout<<"Data masuk"<<endl;
} } main() main() { {
int pil, databaru; int pil, databaru; do
do { {
cout<<"Menu Pilihan Single Linked List dengan Head cout<<"Menu Pilihan Single Linked List dengan Head dan Tail "<<endl;
dan Tail "<<endl;
cout<<"1. Insert Data dari
cout<<"1. Insert Data dari Depan"<<endl;Depan"<<endl;
cout<<"2. Exit"<<endl; cout<<"Masukkan Pilihan Anda cout<<"2. Exit"<<endl; cout<<"Masukkan Pilihan Anda = "; cin>>pil; = "; cin>>pil; switch (pil) switch (pil) { { case 1: case 1: cout<<"Masukkan Data = "; cout<<"Masukkan Data = "; cin>>databaru; cin>>databaru; insertDepan(databaru); insertDepan(databaru); break; break; } } } } while(pil!=2); while(pil!=2); } } Tamp Tampilil an Han H asasilil 
 Penambahan data dari belakang dengan head dan tailPenambahan data dari belakang dengan head dan tail Ilustrasi :
Ilustrasi : 1.
1. List masih kosong (head = tail = NULL)List masih kosong (head = tail = NULL)
2.
2. Masukkan data baru, misal 14Masukkan data baru, misal 14
3.
Script penambahan dari belakang dengan head dan tail Script penambahan dari belakang dengan head dan tail
#include <iostream> #include <iostream> using namespace std; using namespace std; struct TNode struct TNode { {
int data; TNode *next; int data; TNode *next; };
};
TNode *head, *tail; TNode *head, *tail; void init() void init() { { head=NULL; head=NULL; tail=NULL; tail=NULL; } } int cekkosong() int cekkosong() { { if(tail==NULL) if(tail==NULL) { { return 0; return 0; } } else else { { return 1; return 1; } } } }
void tambahBelakang(int databaru) void tambahBelakang(int databaru) {
{
TNode *baru,*bantu; TNode *baru,*bantu; baru = new TNode; baru = new TNode; baru-> data =
baru-> data = databaru;databaru; baru-> next = NULL; baru-> next = NULL; if(cekkosong()==0) if(cekkosong()==0) { { head=baru; head=baru; tail=baru; tail=baru; tail->next = NULL; tail->next = NULL; } } else else
{ tail->next = baru; tail=baru; } cout<<"Data masuk\n"; } main() {
int pil, databaru; do
{
cout<<"Menu Pilihan Single Linked List dengan Head dan Tail "<<endl;
cout<<"1. Insert Data dari Belakang"<<endl; cout<<"2. Exit"<<endl;
cout<<"Masukkan Pilihan Anda = "; cin>>pil; switch (pil) { case 1: cout<<"Masukkan Data = "; cin>>databaru; tambahBelakang(databaru); break; } } while(pil!=2); } Tampilan H asil
Catatan : pada penambahan data di belakang, data akan selalu dikaitkan dengan tail, karena tail terletak di node paling belakang
 Fungsi untuk menampilkan isi linked list dengan head dan tail void tampil() { TNode *bantu; bantu = head; if(cekkosong() == 0) { while(bantu != NULL) {
cout << bantu->data << ends; bantu = bantu->next;
}
cout << endl; }
else
cout << "Masih kosong" << endl; }
Ilustrasi :
 Fungsi menghapus data dari depan void hapusDepan() { TNode *hapus; int d; if (cekkosong() == 0) { if(head != tail) { hapus = head;
d = hapus->data; head = head->next; delete hapus;
} else {
d = tail->data; head = tail = NULL; }
cout << d << " terhapus" << endl; }
else
cout << "Masih kosong" << endl; }
Penjelasan :
1. Function di atas akan menghapus data terdepan (pertama) yang ditunjuk oleh head pada linked list.
2. Penghapusan node tidak boleh dilakukan jika keadaan node sedang ditunjuk oleh pointer, maka harus dilakukan penunjukkan terlebih dahulu dengan pointer hapus pada head, kemudian dilakukan pergeseran head ke node berikutnya sehingga data setelah head menjadi head baru, kemudian menghapus pointer hapus dengan menggunakan perintah delete.
3. Jika tail masih NULL, maka berarti list masih kosong  Penghapusan data dari belakang
Ilustrasi :
 Fungsi penghapusan dari belakang void hapusBelakang() { TNode *bantu,*hapus; int d; if (cekkosong() == 0) { bantu = head; if(head!=tail) { while(bantu->next!=tail) { bantu = bantu->next; } hapus = tail; tail=bantu; d = hapus->data; delete hapus; tail->next = NULL; } else { d = tail->data; head=tail=NULL; } cout<<d<<" terhapus\n"; }
else cout<<"Masih kosong\n"; }
Penjelasan :
1. Function di atas akan menghapus data paling belakang (terakhir) yang ditunjuk oleh tail pada linked list
2. Penghapusan node tidak boleh dilakukan jika keadaan node sedang ditunjuk oleh pointer, maka harus dilakukan penunjukkan terlebih dahulu dengan variabel hapus pada tail, kemudian dibutuhkan pointer bantu untuk membantu pergeseran dari head ke node berikutnya
sampai sebelum tail, sehingga tail dapat ditunjukkan ke bantu tersebut, dan bantu tersebut akan menjadi tail yang baru. Setelah itu hapus pointer hapus dengan menggunakan perintah delete
3. Jika tail masih NULL, maka berarti list masih kosong.
5.7 Double Linked List (Non Circular)
 Double Linked List memiliki 2 buah pointer yaitu pointer next dan prev. Pointer next menunjuk pada node setelahnya dan pointer prev menunjuk pada node sebelumnya
 Pengertian :
 Double : artinya field pointer-nya dua buah dan dua arah, ke node sebelum dan sesudahnya
 Linked List : artinya node-node tersebut saling terhubung satu sama lain
 Non Circular : artinya pointer prev dan next-nya akan menunjuk pada NULL.
 Ilustrasi double linked list
- Setiap node pada linked list mempunyai field yang berisi data dan pointer ke node berikutnya & ke node sebelumnya.
- Untuk pembentukan node baru, mulanya pointer next dan prev akan menunjuk ke nilai NULL.
- Selanjutnya pointer prev akan menunjuk ke node sebelumnya, dan pointer next akan menunjuk ke node selanjutnya pada list  Deklarasi dan pembentukan node baru pada double linked list
- Deklarasi Node : struct TNode { int data; TNode *next; TNode *prev; }
- Pembentukan node baru TNode *baru;
baru=new TNode;
baru->data=databaru; baru->next=NULL; baru->prev=NULL;