Dari Gambar 3.2 terlihat bahwa setiap elemen larik, selain menyimpan data juga menyimpan “alamat” (dalam Gambar 3.2 berupa indeks) sebagai penunjuk (pointer) posisi elemen larik yang mengikutnya. Elemen yang menyimpan data dan “alamat” seperti ini disebut elemen senarai. Jadi senarai adalah sekumpulan elemen bertipe sama, setiap elemen terdiri dari dua bagian, yaitu bagian yang menyimpan informasi dan bagian yang menyimpan alamat elemen berikutnya.
Gambar 3.3 menunjukkan senarai secara lojik
Info Next
First (a)Elemen Senarai
(b) Senarai Kosong First
(c) Senarai Dengan 3 Elemen
Gambar 3.3. (a) Elemen Senarai, (b) Senarai Kosong, (c)Senarai Dengan 3 Elemen
Secara algoritmik, definisi senarai dapat dilihat pada Algoritma 3.1.
Deklarasi global:
type TInfo = integer {atau tipe terdefinisi lainnya}
type Address = pointer to Elemen
type Elemen = record <Info: TInfo, Next: Address>
type Senarai = record <First: Address>
P: Address L: Senarai
{First menyimpan alamat elemen pertama senarai}
{P adalah variabel yang menyimpan alamat sebuah elemen}
{Cara akses:
Info(P): mengakses info elemen yang alamatnya P
Next(P): mengakses alamat elemen setelah elemen dengan alamat P}
procedure Alokasi(output P: Address)
{memesan satu unit penyimpan untuk dijadikan elemen senarai}
{K. Awal: - }
{K.Akhir: P terdefinisi, siap digunakan sebagai elemen list}
procedure DeAlokasi(input P: Address) {K. Awal: P terdefinisi}
{K.Akhir: P dikembalikan ke sistem}
Algoritma 3.1. Deklarasi Senarai
TInfo adalah tipe terdefinisi yang merepresentasikan informasi yang akan disimpan di dalam elemen .
Tipe Address adalah tipe yang menyimpan alamat elemen, bisa berupa indeks larik ataupun alamat memori, tergantung nanti bagaimana senarai direpresentasikan.
Senarai dikenali melalui alamat elemen pertamanya. Dengan demikian jika didefinisikan First adalah alamat elemen pertama, maka elemen berikut dapat diakses secara berurutan melalui Next.
Mengapa harus senarai? Senarai adalah struktur data yang dinamis, ukurannya (banyak elemen) dapat berubah selama eksekusi program. Menghemat memori
Setiap elemen menyimpan “alamat” elemen berikutnya. Ada dua cara untuk merepresentasikan alamat. Jika senarai dibangun menggunakan larik, maka alamat adalah indeks larik. Jika senarai dibangun langsung dari memori, maka alamat adalah alamat memori.
Tipe pointer adalah fasilitas bahasa yang digunakan untuk menangkap ekivalensi dari alamat memori.
Notasi algoritmik untuk tipe pointer adalah sebagai berikut:
Nama tipe: pointer to
Rentang nilai: alamat sel memori
Konstanta: Nil, untuk menyatakan alamat tidak terdefinisi Operator perbandingan: = dan ≠, menghasilkan nilai boolean
Operasi Dasar Terhadap Senarai 1. Create: membuat senarai kosong
2. Traversal: mengunjungi elemen senarai mulai dari elemen pertama sampai elemen terakhir atau elemen tertentu yang diinginkan dan melakukan pemrosesan
3. Insert: menyisipkan elemen 4. Delete: menghapus elemen
5. Bekerja dengan 2 senarai atau lebih 3.3 Membuat senarai kosong
procedure Create(output L: Senarai) {membuat senarai kosong}
{K. Awal: - }
{K.Akhir: tercipta sebuah list kosong, L.First = Nil}
Deklarasi:
Deskripsi:
L.First = Nil
Algoritma 3.2. Membuat Senarai Kosong
3.4 Traversal
Ada dua skema, yaitu skema repeat-until yang memeriksa apakah senarai kosong dan skema while-do tidak memeriksa apakah senarai kosong atau tidak.
Traversal dengan skema repeat - until
procedure Traversal1(input L: Senarai) {traversal list dengan kasus senarai kosong}
{K. Awal: L terdefinisi, mungkin kosong}
{K.Akhir: Semua elemen senarai dikunjungi dan diproses}
Deklarasi:
P: Address Deskripsi:
if L.First = Nil then write (“senarai kosong”) else
Algoritma 3.3. Traversal Dengan Kasus Kosong Traversal dengan skema while-do
procedure Traversal2(input L: Senarai)
{traversal list tanpa penanganan kasus senarai kosong}
{K. Awal: L terdefinisi, mungkin kosong}
{K.Akhir: Semua elemen senarai dikunjungi dan diproses}
Deklarasi:
Algoritma 3.4. Traversal Tanpa Kasus List Kosong
Contoh 3.1: Mencetak semua info elemen senarai
Untuk mencetak semua info elemen senarai berarti harus dilakukan traversal terhadap senarai mulai dari elemen pertama sampai elemen terakhir. Proses yang dilakukan adalah pencetakan.
procedure Cetak(input L: Senarai)
{Mencetak semua info elemen senarai. Jika senarai kosong cetak pesan “senarai kosong”}
{K. Awal: L terdefinisi, mungkin kosong}
{K.Akhir: Semua elemen senarai dikunjungi dan info-nya dicetak}
Deklarasi:
P: Address Deskripsi:
if L.First = Nil then write (“list kosong”) else
P L.First repeat
write (Info(P)) P Next(P) until P = Nil endif
Algoritma 3.5. Mencetak Info Semua Elemen Contoh 3.2: Menghitung banyak elemen
Traversal senarai dan menghitung banyak elemen. Setiap kali sebuah elemen dikunjungi berarti banyak elemen bertambah 1.
Perhatikan ilustrasi berikut:
First First
NEl = 3 NEl = 0
Gambar 3.4. Menghitung Banyak Elemen
procedure HitElemen(input L: Senarai, output NEl: integer) {Menghitung banyak elemen senarai}
{K. Awal: L terdefinisi, mungkin kosong}
{K.Akhir: NEl terdefinisi, yaitu banyak elemen senarai } Deklarasi:
P: Address Deskripsi:
NEl 0 P L.First while P ≠ Nil do NEl NEl + 1 P Next(P) endwhile
Algoritma 3.6. Menghitung Banyak Elemen Contoh 3.3
Buat algoritma untuk menghitung banyak elemen senarai yang info-nya ganjil Perhatikan ilustrasi berikut:
First
NGj = -99
First
NGj = 2
First
NGj = 0
58 73 47 74 60 80
Gambar 3.5. Menghitung Banyak Elemen Ganjil
procedure HitGanjil(input L: Senarai, output NGj: integer) {Menghitung banyak elemen senarai yang info-nya ganjil}
{K. Awal: L terdefinisi, mungkin kosong}
{K.Akhir: NGj terdefinisi, yaitu banyak elemen senarai yang bernilai ganjil. Jika senarai kosong,
maka NGj = -99 } Deklarasi:
P: Address Deskripsi:
if L.First = Nil then NGj -99
else NGj 0 repeat
if Info(P) mod 2 = 1 then NGj NGj + 1
endif
P Next(P) until P = Nil endif
Algoritma 3.7. Menghitung Banyak Elemen yang Info-nya Ganjil Contoh 3.4 : Pencarian
Pencarian adalah menelusuri (traversal) elemen senarai mulai dari elemen pertama sampai elemen yang dicari ditemukan atau sampai elemen terakhir jika yang dicari tidak ditemukan. Proses yang dilakukan selama penelusuran adalah membandingkan apakah info elemen senarai yang dikunjungi sama dengan yang dicari. Jika sama berarti yang dicari ditemukan dan penelusuran dihentikan. Jika info elemen yang dikunjungi tidak sama dengan yang dicari maka penelusuran dilanjutkan ke elemen berikutnya. Ada dua macam algoritma pencarian, yaitu (1) hasil pencarian berupa nilai boolean, true jika yang dicari ditemukan dan false yang dicari tidak ditemukan. (2) Hasil pencarian berupa alamat elemen yang dicari tersebut ditemukan, nil jika yang dicari tidak ditemukan.
Perhatikan ilustrasi pada Gambar 3.6.
(1) Keluaran berupa nilai boolean
Misalkan X yang dicari = 73
(2) Keluaran berupa alamat
First
Misalkan X yang dicari = 73
PX = Nil
Gambar 3.6. Pencarian
procedure Search1(input L: Senarai, input X: TInfo, output Found: boolean)
{Mencari apakah X ada di dalam elemen senarai}
{K. Awal: L terdefinisi, mungkin kosong, X terdefinisi yaitu info yang dijadikan dasar pencarian}
{K.Akhir: Jika X ditemukan maka Found = true,
Jika X tidak ditemukan maka Found = false}
Algoritma 3.8. Pencarian Dengan Keluaran Boolean
procedure Search2(input L: Senarai, input X: TInfo, output PX: Address)
{Mencari apakah X ada di dalam elemen senarai}
{K. Awal: L terdefinisi, mungkin kosong, X terdefinisi yaitu info yang dijadikan dasar pencarian}
{K.Akhir: Jika X ditemukan maka PX adalah alamat elemen tempat X ditemukan
Algoritma 3.9. Pencarian Dengan Keluaran Alamat 3.5 Penyisipan Elemen
1. Penyisipan sebagai elemen pertama 2. Penyisipan sebagai elemen tengah 3. Penyisipan sebagai elemen terakhir Penyisipan Sebagai Elemen Pertama
First
Gambar 7. Penyisipan Sebagai Elemen Pertama
procedure InsertFirst(input/output L: Senarai, input P: Address)
{Menyisipkan P sebagai elemen pertama senarai}
{K. Awal: L terdefinisi, mungkin kosong, P terdefinisi yaitu alamat elemen yang akan disisipkan}
{K.Akhir: P menjadi elemen pertama senarai}
Deklarasi:
Deskripsi:
Next(P) L.First L.First P
Algoritma 3.10. Menyisipkan Sebagai Elemen Pertama Penyisipan Sebagai Elemen Tengah
First
P
First
60 73 60 58 73
58
Sebelum Penyisipan Setelah Penyisipan
Prev Prev
P
Gambar 8. Penyisipan Sebagai Elemen Tengah
procedure InsertAfter(input/output P, Prev: Address) {Menyisipkan P setelah elemen dengan alamat Prev}
{K. Awal: Prev terdefinisi, P terdefinisi yaitu alamat elemen yang akan disisipkan}
{K.Akhir: P menjadi elemen setelah elemen dengan alamat Prev}
Deklarasi:
Deskripsi:
Next(P) Next(Prev) Next(Prev) P
Algoritma 3.11. Menyisipkan Sebagai Elemen Tengah
Penyisipan Sebagai Elemen Terakhir
First
P
First
60 73 60 73 50
58
Sebelum Penyisipan Setelah Penyisipan
Last Last
P
Gambar 3.9. Penyisipan Sebagai Elemen Terakhir
procedure InsertLast(input/output L: Senarai, input P: Address)
{Menyisipkan P sebagai elemen terakhir}
{K. Awal: L terdefinisi, mungkin kosong P terdefinisi yaitu alamat elemen yang akan disisipkan}
{K.Akhir: P menjadi elemen terakhir senarai}
Deklarasi:
Last: Address Deskripsi:
if L.First = Nil then L.First P
else
Last L.First
while Next(Last) ≠ Nil do Last Next(Last) endwhile
Next(Last) P endif
Algoritma 3.12. Menyisipkan Sebagai Elemen Terakhir
Contoh 3.5: Pencarian dan Penyisipan
Buat algoritma untuk mencari keberadaan X di dalam senarai. Jika X tidak ditemukan, maka alokasikan sebuah elemen dengan alamat P, simpan X sebagai Info(P) dan sisipkan P sebagai elemen pertama senarai. Perhatikan Gambar 3.10.
First Kasus (1) jika X tidak ditemukan
First First
58 73 58 73
K. Awal K.Akhir
Mis. X = 73 Kasus (2) jika X ditemukan
Gambar 3.10. Pencarian dan Penyisipan procedure CaridanSisip(input/output L: Senarai, input X: TInfo)
{mencari keberadaan X, jika tidak ditemukan maka alokasikan sebuah elemen dengan alamat P, simpan X sebagai Info(P) dan sisipkan P sebagai elemen pertama senarai}
{K. Awal: L terdefinisi, X terdefinisi}
{K.Akhir: Jika X tidak ditemukan, maka X menjadi elemen pertama senarai}
Alokasi(P)
Algoritma 3.13. Pencarian dan Penyisipan Contoh 3.6: Penyisipan sebagai elemen ke-k
Tulis algoritma untuk menyisipkan elemen sebagai elemen ke-k senarai L.
Perhatikan Gambar 3.11.
Kasus (2) Senarai tidak kosong, k = 1
K. Akhir
Kasus (3) Senarai tidak kosong, k ≠ 1
36
Gambar 3.11 Penyisipan Sebagai Elemen Ke-k
procedure SisipK(input/output L: Senarai, input P: Address, input k: integer)
{menyisipkan P sebagai elemen ke-k pada senarai L}
{K. Awal: L terdefinisi, P terdefinisi, k terdefinisi >= 1}
{K.Akhir: P menjadi elemen ke-k senarai L}
Deklarasi:
Algoritma 3.14. Penyisipan Sebagai Elemen ke-k 3.6 Menghapus Elemen
1. Menghapus Elemen Pertama 2. Menghapus Elemen Tengah 3. Menghapus Elemen Terakhir
Menghapus Elemen Pertama
Gambar 3.12. Menghapus Elemen Pertama
procedure DeleteFirst(input/output L: Senarai, output P:Address)
{menghapus elemen pertama senarai}
{K. Awal: L terdefinisi, tidak kosong}
{K.Akhir: P adalah alamat elemen yang dihapus}
Deklarasi:
Deskripsi:
P L.First
L.First Next(L.First)
Algoritma 3.14. Menghapus Elemen Pertama Menghapus Elemen Tengah
First
60 58 73
Sebelum Penghapusan Setelah Penghapusan
First
60 58 73
P Prev
Prev
Gambar 3.13. Menghapus Elemen Tengah
procedure DeleteAfter(input/output P, Prev: Address) {menghapus elemen setelah elemen dengan alamat Prev}
{K. Awal: Prev terdefinisi}
{K.Akhir: P adalah alamat elemen yang dihapus}
Deklarasi:
Deskripsi:
P Next(Prev)
Next(Prev) Next(Next(Prev))
Algoritma 3.14. Menghapus Elemen Tengah
Menghapus Elemen Terakhir
First
60 58 73
Sebelum Penghapusan Setelah Penghapusan
First
60 58 73
P PrevLast
PrevLast Last Last
Gambar 3.14. Menghapus Elemen Terakhir procedure DeleteLast(input/output L: Senarai, output P:Address)
{menghapus elemen terakhir senarai}
{K. Awal: L terdefinisi, tidak kosong}
{K.Akhir: P adalah alamat elemen yang dihapus}
Deklarasi:
Last, PrevLast: Address Deskripsi:
PrevLast Nil Last L.First
while Next(Last) ≠ Nil do PrevLast Last
Last Next(Last) endwhile
P Last
Next(PrevLast) Nil
Algoritma 3.15. Menghapus Elemen Terakhir
Contoh 3.7: Hapus X
Buat algoritma untuk elemen yang info-nya = X. Perhatikan Gambar 3.14.
First
60 58 73
K. Awal K.Akhir
Kasus (1) jika X tidak ditemukan
Kasus (2) jika X ditemukan First
Gambar 3.15. Pencarian dan Penghapusan
procedure HapusX(input/output L: Senarai,
input X: TInfo, output P: Address) {mencari keberadaan X, jika ditemukan maka hapus elemen X}
{K. Awal: L terdefinisi, X terdefinisi}
{K.Akhir: Jika X ditemukan P adalah alamat elemen yang dihapus. Jika X ditemukan, maka P = Nil}
Algoritma 3.17. Mencari dan Menghapus
3.7 Bekerja Dengan Dua atau Lebih Senarai 1. Penyambungan Senarai (Konkat) 2. Penggabungan Senarai (Merger) 3. Salin Senarai (Copy)
4. Balik Senarai (Reverse)
5. Mengambil Info Tertentu (Query)
Penyambungan Senarai (Konkat)
Menyambung senarai L1 dengan senarai L2. Senarai L1 berada “di depan”
L2.First
42 29
K. Awal
K.Akhir L1.First
60 58 73
L1.First
60 58 73 42 29
Gambar 3.16. Penyambungan Senarai
procedure Konkat(input/output L1: Senarai, input L2: Senarai) {menyambung senarai L1 dengan senarai L2, dengan senarai L1 berada di depan}
{K. Awal: L1, L2 terdefinisi}
{K.Akhir: L2 tersambung dengan L1}
Deklarasi:
P: Address Deskripsi:
P L1.First
while Next(P) ≠ Nil do P Next(P)
endwhile
Next(P) L2.First
Algoritma 3.18. Menghapus Elemen Tengah
Penggabungan Senarai (Merger)
Menggabung senarai L1 dan L2 yang info-nya terurut dari kecil ke besar, L3 adalah hasil penggabungan dan info-nya tetap terurut.
L2.First
procedure Merger(input L1,L2: Senarai, output L3: Senarai)
{Menggabung senarai L1 dengan L2 yang info-nya terurut dari kecil ke besar. Senarai L3 merupakan penggabungan, tetap terurut}
{K. Awal: L1, L2 terdefinisi, info-nya terurut dari kecil ke besar}
{K.Akhir: L3 terdefinisi merupakan hasil penggabungan L1 dengan L2 dan tetap terurut}
Alokasi(Q)
Algoritma 3.19. Penggabungan Senarai Salin Senarai (Copy)
Membuat salinan senarai L1 ke L2
K. Awal K.Akhir
L1.First
45 60 80
L2.First
45 60 80
Gambar 3.17. Menyalin Senarai
procedure Copy(input L1: Senarai, output L2: Senarai) {menyalin senarai L1 ke senarai L2}
{K. Awal: L1terdefinisi}
{K.Akhir: L2 terdefinisi, merupakan salinan dari L1}
Deklarasi:
Algoritma 3.20. Penggabungan Senarai
Balik Senarai (Reverse)
Membalik senarai L1, hasilnya adalah senarai L2
K. Awal K.Akhir
L1.First
45 60 80
L2.First
80 60 45
Gambar 3.18. Balik Senarai
procedure Reverse(input L1: Senarai, output L2: Senarai) {menyalin senarai L1 ke senarai L2 secara terbalik}
{K. Awal: L1terdefinisi}
{K.Akhir: L2 terdefinisi, merupakan balikan dari L1}
Deklarasi:
P,Q: Address Deskripsi:
Create(L2) P L1.First while P ≠ Nil do Alokasi(Q) Next(Q) Nil Info(Q) Info(P) InsertFirst(L2,Q) P Next(P) endwhile
Algoritma 3.21. Membalik Senarai
Mengambil Info Tertentu (Query)
Contoh 3.8: diketahui senarai L1, akan diambil elemen senarai yang info-nya <
X, hasilnya disimpan di senarai L2
K. Awal
K.Akhir L1.First
70 53 80
L2.First
53 40 54
40 54 65
Mis. X = 55
Gambar 3.19. Mengambil Info Tertentu
procedure QueryX(input L1: Senarai, input X: TInfo, output L2: Senarai)
{menyalin senarai L1 yang info-nya < X ke senarai L2 } {K. Awal: L1terdefinisi}
{K.Akhir: L2 terdefinisi, merupakan hasil query, semua info- nya < X}
Deklarasi:
P,Q: Address Deskripsi:
Create(L2) P L1.First while P ≠ Nil do if Info(P) < X then Alokasi(Q)
Next(Q) Nil Info(Q) Info(P) InsertLast(L2,Q) endif
P Next(P) endwhile
Algoritma 3.22. Mengambil informasi tertentu