Queue Queue (antrian) adalah kumpulan data yang penambahan elemennya dilakukan pada suatu ujung (bagian belakang) dan penghapusannnya dilakukan pada ujung yang lain (bagian depan). Prinsip ini biasa juga disebut dengan First In First Out (masuk pertama keluar pertama). Dengan kata lain urutan keluar suatu elemen data urutannya sama dengan urutan masuknya. Implementasi Queue dengan Array Seperti dijelaskan sebelumnya, queue adalah kumpulan data. Untuk mengimplementasikan kumpulan data biasanya kita menggunakan array. Array dapat digunakan untuk menyimpan data dan dengan dua variabel yang berisi nilai index kepala dan ekor queue. Dua index penunjuk ini berguna ketika akan dilakukan penambahan dan penghapusan. Pada gambar 1 dapat dilihat struktur queue dengan dua penunjuk. Gambar 1. Queue Pada queue dikenal dua operasi dasar yaitu penambahan dan penghapusan. Penambahan akan mengubah nilai dari ekor. Pada saat data ditambahkan, nilai ekor akan menuju index berikutnya (jika tidak penuh) lalu mengisi data pada tempat tersebut. Jika terjadi penghapusan maka data yang akan dihapus adalah data yang ditunjuk oleh index kepala. Hal ini memperjelas penggunaan FIFO dalam queue. Jika kita mengimplementasikan queue dengan array penambahan data terbatas pada ukuran array yang digunakan. Hal lain yang harus diperhatikan adalah pada saat penghapusan data. Pada saat penghapusan data, harus terdapat pemeriksaan apakah queue kosong. Jika kosong maka penghapusan dibatalkan karena tidak mungkin menghapus data dari queue yang sudah kosong. Cara pertama yang dapat dilakukan untuk mengimplementasikan queue dengan array adalah sebagai berikut. Ketika terjadi penambahan data maka index ekor akan ditambah dengan satu dan array dengan index tersebut akan diisikan dengan data. Ketika terjadi Pusat Pengembangan Pendidikan Universitas Gadjah Mada 1
penghapusan nilai index kepala akan ditambahkan dengan satu. Ilustrasi penambahan dan penguranagan dapat dilihat pada gambar 2. Gambar 2. Ilustrasi Cara Pertama Pada Gambar 2 dapat dilihat bahwa data pada kepala queue tidak dihapus, hanya penunjuknya saja yang digeser ke index berikutnya. Kode program secara lengkap dapat dilihat pada Program 1. Program 1. Implementasi Cara Pertama 1 program array_queue1; 2 uses crt; 3 4 const max = 100; 5 type antri = array[1..max] of char; 6 var antrian : antri; 7 depan,belakang : integer; 8 i : integer; 9 10 11 procedure tambah(c : char); 12 Begin 13 if (belakang = max) then 14 Begin Pusat Pengembangan Pendidikan Universitas Gadjah Mada 2
15 Writeln('Queue penuh!'); 16 exit; 17 end; 18 19 writeln('tambah: ',c); 20 belakang := belakang + 1; 21 antrian[belakang] := c; 22 end; 23 24 procedure hapus; 25 Begin 26 if (depan > belakang) then 27 Begin 28 Writeln('Queue kosong!'); 29 exit; 30 end; 31 writeln('hapus: ',antrian[depan]); 32 depan := depan + 1; 33 end; 34 35 procedure tampil_queue; 36 var i : integer; 37 Begin 38 writeln; 39 writeln('data pada antrian sekarang:'); 40 for i:= depan to belakang do 41 Begin 42 Writeln(antrian[i]); 43 end; 44 end; 45 46 procedure press_any_key_to_continue; 47 Begin 48 writeln('press any key to continue!'); 49 writeln; 50 readkey; 51 end; 52 53 54 Begin 55 clrscr; 56 belakang := 0; 57 depan := 1; 58 59 tambah('a'); 60 tambah('b'); 61 tambah('c'); 62 tambah('d'); Pusat Pengembangan Pendidikan Universitas Gadjah Mada 3
63 tambah('e'); 64 tambah('f'); 65 tambah('g'); 66 tambah('h'); 67 press_any_key_to_continue; 68 69 tampil_queue; 70 press_any_key_to_continue; 71 72 hapus; 73 hapus; 74 hapus; 75 press_any_key_to_continue; 76 77 tampil_queue; 78 press_any_key_to_continue; 79 end. Cara pertama kurang efisien dalam penggunaan memori. Blok memori data yang sudah terhapus tidak dapat digunakan lagi. Sehingga blok memori yang dapat digunakan untuk menyimpan data menjadi semakin berkurang setiap terjadi penghapusan data. Untuk memecahkan masalah tersebut dilakukan pergeseran setiap terjadi penghapusan data. Ketika data dihapus maka seluruh item array dari index kepala + 1 hingga ekor akan dipindahkan ke index sebelumnya. Dengan cara ini, nilai array dengan index kepala akan tertimpah oleh nilai sebelumnya (terhapus). Pada teknik ini tidak terjadi perubahan penunjuk kepala pada saat penghapusan data. Pada saat penambahab, yang terjadi sama dengan cara sebelemunya. Gambar 3 menunjukan ilustrasi penghapusan cara kedua. Pusat Pengembangan Pendidikan Universitas Gadjah Mada 4
Gambar 3. Ilustrasi penghapusan cara kedua Pada cara kedua tersebut dapat dilihat tidak ada pemborosan memori. Sehingga masalah pada cara pertama sudah terselesaikan. Kode program secara lengkap dapat dilihat pada Program 2. Program 2. Implementasi Cara Kedua 1 program array_queue2; 2 uses crt; 3 4 const max = 100; 5 type antri = array[1..max] of char; 6 var antrian : antri; 7 depan,belakang : integer; 8 i : integer; 9 10 11 procedure geser; 12 var i : integer; 13 Begin 14 if (belakang > 1) then 15 Begin 16 for i:= 1 to belakang - 1 do 17 Begin 18 antrian[i] := antrian[i+1]; 19 end; 20 end; 21 end; Pusat Pengembangan Pendidikan Universitas Gadjah Mada 5
22 23 procedure tambah(c : char); 24 Begin 25 if (belakang = max) then 26 Begin 27 writeln('queue penuh!'); 28 exit; 29 end; 30 writeln('tambah: ',c); 31 belakang := belakang + 1; 32 antrian[belakang] := c; 33 end; 34 35 procedure hapus; 36 Begin 37 if (belakang = 0) then 38 Begin 39 writeln('queue kosong!'); 40 exit; 41 end; 42 writeln('hapus: ',antrian[depan]); 43 geser; 44 belakang := belakang - 1; 45 end; 46 47 procedure tampil_queue; 48 var i : integer; 49 Begin 50 writeln; 51 writeln('data pada antrian sekarang:'); 52 for i:= depan to belakang do 53 Begin 54 writeln(antrian[i]); 55 end; 56 end; 57 58 procedure press_any_key_to_continue; 59 Begin 60 writeln('press any key to continue!'); 61 writeln; 62 readkey; 63 end; 64 65 66 Begin 67 clrscr; 68 belakang := 0; 69 depan := 1; Pusat Pengembangan Pendidikan Universitas Gadjah Mada 6
70 71 tambah('a'); 72 tambah('b'); 73 tambah('c'); 74 tambah('d'); 75 tambah('e'); 76 tambah('f'); 77 tambah('g'); 78 tambah('h'); 79 press_any_key_to_continue; 80 81 tampil_queue; 82 press_any_key_to_continue; 83 84 hapus; 85 hapus; 86 hapus; 87 press_any_key_to_continue; 88 89 tampil_queue; 90 press_any_key_to_continue; 91 end. Ketika data yang terdapat pada queue masih sedikit, cara kedua tidak akan mendatangkan masalah. Namun ketika data sudah berjumlah besar akan terjadi kelambatan pada saat penghapusan data. Sebagai contoh ketika data yang berada pada array sudah berjumlah 1000 data. Maka ketika terjadi penghapusan diperlukan 99 pemindahan data. Cara yang ketiga yang digunakan adalah dengan menggunakan array melingkar. Dengan cara penambahan maupun penghapusan data mirip dengan cara pertama namun dengan ketentuan berbeda pada penentuan kepala dan ekor. Pada saat penambahan di kedua cara sebelumnya jika nilai index ekor sudah mencapai nilai maximum maka disimpulkan bahwa queue telah penuh. Pada cara ini, nilai index ekor sudah mencapai nilai maximum nilai ekor akan melakukan pemeriksaan pada index pertama dari array. Jika bukan merupakan kepala maka index ekor merupakan nilai index pertama array. Pada saat penghapusan, yang terjadi adalah sebaliknya. Ketika data pada index array paling awal dihapus, akan dilakukan pemeriksaan apakah data pada nilai index ekor merupakan data terakhir atau bukan. Jika bukan maka penunjuk kepala akan menunjuk kepada index array terakhir. Gambar 4 menunjukan ilustrasi penambahan dan penghapusan. Pusat Pengembangan Pendidikan Universitas Gadjah Mada 7
Gambar 4. Ilustrasi Cara Ketiga Dengan cara ini permasalahan cara petama dan kedua dapat diselesaikan. Kode program secara lengkap dapat dilihat pada Program 3. Program 3. Implementasi Cara Ketiga 1 program array_queue3; 2 uses crt; 3 4 const max = 10; 5 type antri = array[1..max] of char; 6 var antrian : antri; 7 depan,belakang : integer; 8 i : integer; 9 jumlah : integer; 10 11 12 13 14 procedure tambah(c : char); 15 var tmp : integer; 16 Begin 17 if (jumlah = 10) then 18 Begin 19 Writeln('Queue penuh!'); 20 exit; Pusat Pengembangan Pendidikan Universitas Gadjah Mada 8
21 end; 22 writeln('tambah: ',c); 23 if (belakang = max) then 24 Begin 25 tmp := belakang; 26 belakang := 1; 27 End 28 Else 29 belakang := belakang + 1; 30 31 antrian[belakang] := c; 32 jumlah := jumlah + 1; 33 end; 34 35 procedure hapus; 36 Begin 37 writeln('hapus: ',antrian[depan]); 38 if (jumlah = 0) then 39 Begin 40 Writeln('Queue kosong'); 41 exit; 42 End 43 Else 44 Begin 45 if (depan = max) then 46 depan := 1 47 Else 48 depan := depan + 1; 49 end; 50 jumlah := jumlah - 1; 51 end; 52 53 procedure tampil_queue; 54 var i : integer; 55 Begin 56 writeln; 57 writeln('data pada antrian sekarang:'); 58 i:= depan; 59 Repeat 60 Begin 61 Writeln(antrian[i]); 62 if (i = max) then 63 i := 1 64 Else 65 i := i + 1; 66 end; 67 until (i = belakang+1); 68 Pusat Pengembangan Pendidikan Universitas Gadjah Mada 9
69 end; 70 71 Procedure press_any_key_to_continue; 72 Begin 73 writeln('press any key to continue!'); 74 writeln; 75 readkey; 76 end; 77 78 79 Begin 80 clrscr; 81 belakang := 0; 82 depan := 1; 83 jumlah := 0; 84 85 tambah('a'); 86 tambah('b'); 87 tambah('c'); 88 tambah('d'); 89 tambah('e'); 90 tambah('f'); 91 tambah('g'); 92 tambah('h'); 93 press_any_key_to_continue; 94 95 tampil_queue; 96 press_any_key_to_continue; 97 98 hapus; 99 hapus; 100 hapus; 101 press_any_key_to_continue; 102 103 tampil_queue; 104 press_any_key_to_continue; 105 106 tambah('i'); 107 tambah('j'); 108 tambah('k'); 109 tambah('l'); 110 tambah('m'); 111 tambah('n'); 112 tambah('o'); 113 press_any_key_to_continue; 114 115 tampil_queue; 116 press_any_key_to_continue; Pusat Pengembangan Pendidikan Universitas Gadjah Mada 10
117 118 end. Implementasi Queue dengan pointer Implementasi dengan array memiliki keterbatasan jumlah data yang dapat disimpan pada queue. Jika dilihat penjelasan sebelumnya strutktur queue dapat diimplememntasikan sebagai struktrur linked list dengan perlakukan khusus. Sebelumnya telah dijelaskan untuk memanipulasi dibutuhkan dua penunjuk. Maka pada linked list juga terdapat kebutuhan yang sama. Penunjuk pertama akan menunjuk kepada kepala list (merupakan kepala dari queue) dan penunjuk yang kedua menunjuk kepada item terakhir pada list (merupakan ekor dari queue). Linked list yang digunakan bisa linked list satu arah maupun dua arah. Pada pembahasan ini akan diimplementasikan dengan linked list satu arah. Struktur queue dapat dilihat pada Gambar 5. Gambar 5. Struktur Queue dengan Linked List Pada saat inisialisasi pointer kepala dan ekor akan menunjuk ke nil. Ini menunjukan bahwa queue masih kosong. Pada saat penambahan, cara yang dilakukan sama seperti penambahan linked list satu arah untuk data terakhir hanya ditambah dengan penentuan pointer ekor. Pada saat penghapusan caranya sama pula dengan cara penghapusan linked list data pertama. Kode program secara lengkap dapat dilihat pada Program 4. Program 4. Implementasi Queue dengan Pointer 1 program pointer_queue; 2 uses crt; type item = ^simpul; {tipe data ini digunakan untuk menunjuk 1 3 item queue} simpul = record {record ini digunakan untuk struktur item 4 queue} 5 berikut : item; 6 data : char; Pusat Pengembangan Pendidikan Universitas Gadjah Mada 11
7 end; 8 var kepala : item; 9 ekor : item; 10 11 12 { 13 Procedure untuk menambah data ke queue. 14 parameter: 15 dt : char -> data yang akan ditambahkan 16 } 17 procedure tambah(dt : char); 18 var baru : item; 19 Begin 20 writeln('tambah: ',dt); 21 {buat data baru, set penunjuk berikut ke nil, dan isi data dengan 22 karakter yang ingin ditambahkan} 23 baru := new(item); 24 baru^.berikut := nil; 25 baru^.data := dt; 26 27 {jika queue masih kosong, set data baru sebagai kepala dan ekor} 28 if (kepala = nil) then 29 Begin 30 kepala := baru; 31 ekor := baru; 32 End 33 Else {jika queue sudah terisi, simpan data baru di tempat yang paling akhir 34 dan set sebagai ekor} 35 Begin 36 ekor^.berikut := baru; 37 ekor := ekor^.berikut; 38 end; 39 end; 40 41 { 42 Procedure untuk menghapus data dari queue. 43 } 44 procedure hapus; 45 var curr : item; 46 Begin 47 48 {jika ekor bernilai nil maka artinya queue kosong} 49 if (ekor = nil) then 50 Begin 51 writeln('queue kosong!'); 52 exit; 53 end; Pusat Pengembangan Pendidikan Universitas Gadjah Mada 12
54 55 {jika data merupakan data terakhir, langsung hapus data tersebut} 56 if (kepala = ekor) then 57 Begin 58 Writeln('HAPUS: ',ekor^.data); 59 Dispose(ekor); 60 ekor := nil; 61 End {jika data bukan merupakan data terakhir,set kepala ke data berikutnya, 62 hapus data kepala sebelumnya} 63 Else 64 Begin 65 Writeln('HAPUS: ',kepala^.data); 66 curr := kepala; 67 kepala := kepala^.berikut; 68 Dispose(curr); 69 end; 70 end; 71 72 73 74 75 { 76 Procedure yang digunakan untuk menampilkan semua data yang ada pada queue. 77 } 78 procedure tampil_semua; 79 var curr : item; 80 Begin 81 {set penunjuk ke kepala} 82 curr := kepala; 83 84 {tuliskan nilai data dari awal hingga akhir} 85 while (curr <> nil) do 86 Begin 87 write(curr^.data,' '); 88 curr := curr^.berikut; 89 end; 90 writeln; 91 end; 92 93 94 Begin 95 {set kepala dan ekor untuk menunjuk ke nil} 96 kepala := nil; 97 ekor := nil; 98 clrscr; 99 100 {contoh penggunaan procedure} 101 tambah('a'); Pusat Pengembangan Pendidikan Universitas Gadjah Mada 13
102 tambah('b'); 103 tambah('c'); 104 tambah('d'); 105 tambah('e'); 106 tambah('f'); 107 tampil_semua; 108 hapus; 109 hapus; 110 hapus; 111 hapus; 112 tampil_semua; 113 readkey; 114 end. Queue Berprioritas Pusat Pengembangan Pendidikan Universitas Gadjah Mada 14