NOTASI POLISH, REKURSIF, STACK, QUEUE
BAB VII HASHING DAN KOMPRESI
VII.1. KONSEP HASH
Tabel hashing digunakan untuk mengimplementasikan kamus dalam waktu konstan per operasi. Tabel hash mendukung pemanggilan dan penghapusan pada beberapa item yang telah dinamai sebelumnya.
Untuk mengimplementasikan hash dapat mempergunakan array, dimana array tersebut akan diinisialisasi dengan indeks-indeks tertentu untuk melaksanakan proses penyisipan data dengan memetakan item-item ke dalam indeks dikenal fungsi.
Fungsi hash digunakan untuk mengkonversi suatu item yang bernilai integer dengan indeks array dimana item tersimpan. Jika fungsi hash satu ke satu, kita dapat mengakses item dengan indeks arraynya sendiri sedangkan yang lainnya sebagian item mengambil beberapa indeks yang sama dan akan mengakibatkan tabrakan (collision).
3 2 1 Misalnya suatu fungsi polinomial : A 0
+ A 1 x + A 0 x dapat dievaluasi
sebagai (((A3)x + A 2 )x + A 1 )x + A 0
Metode pemilihan key adalah :
1. Metode pembagian modulus (mod) yaitu menggunakan sisa dari setiap item data, dimana f(key) = h(key) = k mod b ; dimana k adalah key dan b adalah jumlah blok yang tersedia (biasanya bilangan prima).
2. Metode midsquare yaitu masing-masing item-item data yang akan disimpan dikwadratkan, kemudian memilih blok (bucket) penampung sesuai dengan nilai digit yang di tengah dari hasil data yang dikuadratkan tersebut.
Misalnya jumlah blok (bucket) = 13
Gambar 7.1. Metode midsquare
3. Metode penjumlahan digit yaitu setiap digit dari suatu bilangan dijumlah dan kemudian data tersebut disimpan pada blok yang sesuai
Contoh :
Diktat : KBMI3305 - Struktur Data
f(K)= 1+6+9 5+2+9 2+2+5 2+5+6 = 16 16 9 13
Collision Jenis-jenis hashing :
1. Open hashing (hashing terbuka) Open hash (external hash) adalah suatu table dimana proses pertukaran item data dengan pointer masing-masing (tidak terpisahkan) tidak terbatas
2. Close hashing (hashing tertutup) Proses pemetaan data dalam tabel dengan indeks masing-masing, dimana kelemahannya sering terjadi collision.
Untuk mengatasi collision terdapat beberapa cara :
1. Metode separate chaining Bahwa tabel hash T[0], T[1], T[2], … , T[n] akan berisi header list yang merujuk list dengan nilai f(K). Setiap lokasi berisi header list pada elemen data f(key) = i. Metode ini membutuhkan temporary space (tempat tambahan)
2. Metode closed chaining Merupakan modifikasi separate chaining dimana setiap item data ditambahkan link[i] yang merujuk item data selanjutnya. Proses ini akan selalu mencari tempat yang kosong untuk memetakan data, sedang pencarian biasanya dilakukan mulai dari posisi N sampai dengan posisi 1 dengan catatan tidak ditemukan collision.
3. Linier probing dan quadratic probing (open addressing) Merupakan metode chaining yang secara sekuensial yang tidak menggunakan space untuk link item data.
Probe adalah suatu proses perbandingan nilai data pertama dengan data lain. Probe minimum (terbaik) = 1 berarti kompleksitasnya O(N) = 1 dan probe maksimum (terburuk) = N berarti kompleksitasnya O(N) = N (terurut) dan probe rata-rata = (1 + n)/2 berarti kompleksitasnya O(1+N)/2 = (1 + N)/2 dan probe kegagalan adalah O(N) = 0.
Perhatikan contoh berikut : Diberikan deretan data adalah : 3, 13, 23, 15, 16, 26, 27, 37, 47, 50 data-data ini akan dipetakan ke dalam 13 blok (bucket) untuk menyimpan item-item data sebagai berikut :
- f(3) = 3 mod 13 = 3 - f(13) = 13 mod 13 = 0 - f(23) = 23 mod 13 = 10
Collision
- f(15) = 15 mod 13 = 2 - Collision f(16) = 16 mod 13 = 3
- f(23) = 26 mod 13 = 0 - f(27) = 27 mod 13 = 1 - f(37) = 37 mod 13 = 11 - f(47) = 47 mod 13 = 8
Collision
- f(50) = 50 mod 13 = 11
Diktat : KBMI3305 - Struktur Data
VII.2. LINIER PROBING
Merupakan pencarian secara sekuensial dalam array, pencarian dilakukan nulai dari posisi awal sampai dengan akhir tabel. Jika collision pada suatu alamat maka akan dicari alamat kosong kemudian kembali ke awal pengalamatan.
Data : 3 13 23 15 16 26 27 37 47 50 F(key) : 3 0 10 2 3 0 1 11 8 11 Maka :
0 1 2 3 4 5 6 7 8 9 10 11 12 ( 13 blok/bucket )
Langkah 1 .. 4
f(16)=3 terjadi collision (ada data dalam blok tersebut sebelumnya
maka dilakukan dengan linier probing dengan
f I (key) = (f I-1 (key))+1) mod b
f(16) = (3+1) mod 13 = 4
0 1 2 3 4 5 6 7 8 9 10 11 12 ( 13 blok/bucket
Langkah 1 .. 5
F(26)=0 terjadi collision maka f(26)=0+1 mod 13 = 1
0 1 2 3 4 5 6 7 8 9 10 11 12 ( 13 blok/bucket
Langkah 1 .. 6
F(27) = 1 terjadi collision maka = 1+1 mod 13 = 2 (collision)
= 2+1 mod 13 = 3 (collision) = 3+1 mod 13 = 4 (collision)
= 4+1 mod 13 = 5
0 1 2 3 4 5 6 7 8 9 10 11 12 ( 13 blok/bucket
Langkah 1 .. 9
F(50)=11 terjadi collision maka = 11+1 mod 13 = 12
0 1 2 3 4 5 6 7 8 9 10 11 12 ( 13 blok/bucket
Gambar 7.2. Proses linier probing
Diktat : KBMI3305 - Struktur Data
Jadi melihat proses pemetaan data ke dalam array maka dapat kita lihat berapa kali proses probing, seperti diperlihatkan pada tabel berikut di bawah ini :
Tabel 7.1. Proses probing Key
Fungsi
Probe (kali)
f(3)=3 f(13)=0 f(23)=10 f(15)=2 f(16)=3 f(16)=4 f(26)=0 f(26)=1 f(27)=1 f(27)=2 f(27)=3 f(27)=4 f(27)=5 f(37)=11 f(47)=8 f(50)=11 f(50)=12
1 Total
VII.3. QUADRATIC PROBING
Proses mengkwadratkan posisi-posisi elemen data, kemudian membagi (mod) setiap elemen data, misalnya x = 5 bila B = 100 maka alamat hash (x) = 5 2 mod 100 = 25 untuk menghindari collision digunakan quadratic probing.
Misalnya h(x) = y maka h 2 (x) = (y 2 + y) mod B atau h i (x) = (h i-1 (x) + P) mod B ; dimana p = 1,2,3… Hash function mengevaluasi H kemudian mencoba H 2 +1 2 ;H 2 +2 2 ;H 2 +3 2 ; …; H 2 +n 2 ; dengan qwadratic probing dapat diselesaikan dilakukan dengan 2 cara :
Cara I :
Maka h(x) x mod 7 dengan demikian :
Jumlah probe Rata-rata probe = ----------------- Jumlah data = 17/10 = 1,7 ≈ 2 kali
Terdapat 10 blok/bucket Primer 7 blok/bucket Averflow 3 blok/bucket
h(2) = 2 mod 7 = 2 h(3) = 3 mod 7 = 3
Langsung home address
Diktat : KBMI3305 - Struktur Data
Berarti :
Key : 2 3 5 7 11 13 17 19 23 29
Probe (kali) : 1 1 1 1 1 1 2 3 4 1 Total probe = 16 kali
Rata-rata probe = 16/10 = 1,6 ≈ 2 kali
Collision terjadi sebanyak 6 kali
Cara II :
Terdapat 10 blok/bucket
Tabel 7.2. Proses infinitive probing Indeks Key
Modulo
Address Probe Collision
Sehingga untuk sikuensi data diatas apabila diselesaikan dengan quadratic probing akan terjadi collision yang tidak terbatas (infinity) seperti pada item data 23 (tabel 7.2)
Gambar 7. 4. Infinitive Probing
Kasus : Selesaikan dengan quadratic probing kasus berikut : Diberikan key-key yang akan diinput dalam tabel hash “satu”, “dua”, “tiga”, “empat”, “lima”, “enam”, “tujuh”, “delapan”, “sembilan”, “sepuluh”.
Diktat : KBMI3305 - Struktur Data
Spesifikasi : - Jumlah blok/bucket (ukuran hash) = 17 (indeks 0 sampai dengan 16) - Fungsi hash H(x) berdasarkan metode perkalian dengan A = 0.618 - Fungsi ordinal () total bilangan alpabetik dari huruf-huruf pada key (“a”=1, “b”=2, “c”=3, ..., “z”=26)
- Coallision dipecahkan dengan cara rehashing dengan fungsi h 2 (x,i)=-i * ((ord*(x)%5)+1) sehingga penempatan probing ke i adalah h i (x) = h 1 (x) + h 2 (x) dengan i =1,2,3, …
Tunjukkan urutan penempatan key-key tersebut dalam tabel dan berapa jumlah collision yang terjadi pada masing-masing penempatan key. Jawab :
Tabel 7.3. Konversi alpabetik dengan fungsi ordinal Ord() Ordinal * A Fractional (AK) Ord(satu) = 19+1+20+21 = 61
61 * 0.618 = 32,698 0.698 Ord(dua) = 4 + 21 + 1 = 26
26 * 0.618 = 16.068 0.068 Ord(tiga) = 20 + 9 + 7 + 1 = 37
0.866 Ord(empat) = 5 + 13 + 16 + 1 + 20 = 55
0.990 Ord(lima) = 12 + 9 + 13 + 1 = 35
0.630 Ord(enam) = 5 + 14 + 1 + 13 = 33
0.394 Ord(tujuh) = 20 + 21 + 10 + 21 + 8 = 80
0.754 Ord(sembilan) = 19+5+13+2+9+12+1+14=75
Ord(delapan) = 4+5+12+1+16+1+14=53 32.754
0.350 Ord(sepuluh) = 19+5+16+21+12+21+8=102
Sebelum melakukan fungsi rehashing terhadap keseluruhan hasil ordinal huruf-huruf dari masing-masing item data diatas maka dapat dilakukan dengan fungsi floor (pendekatan pembulatan nilai ke bawah) pada fungsi hash H(x), seperti pada tabel berikut :
Tabel 7.4. Fungsi rehashing Fungsi hash
Rehashing
H(x) = ⎣m.frac(AK)⎦
H 2 (x,i) = -i * ((ord(x) % 5) + 1) H(satu) = ⎣17 * 0.698 ⎦ = 11
H 2 (x,1) = -1 * (61 % 5 + 1) = -2 H(dua) = ⎣17 * 0.068 ⎦ = 1
H 2 (x,2) = -1 * (26 % 5 + 1) = -4 H(tiga) = ⎣17 * 0.866 ⎦ = 14
H 2 (x,3) = -1 * (37 % 5 + 1) = -9 H(empat) = ⎣17 * 0.990 ⎦ = 16
H 2 (x,4) = -1 * (55 % 5 + 1) = -4 H(lima) = ⎣17 * 0.630 ⎦ = 10
H 2 (x,5) = -1 * (35 % 5 + 1) = -5 H(enam) = ⎣17 * 0.394 ⎦ = 6
H 2 (x,6) = -1 * (33 % 5 + 1) = -24 H(tujuh) = ⎣17 * 0.440 ⎦ = 7
H 2 (x,7) = -1 * (80 % 5 + 1) = -7 H(delapan) = ⎣17 * 0.754 ⎦ = 12
H 2 (x,8) = -1 * (53 % 5 + 1) = -32 H(sembilan) = ⎣17 * 0.350 ⎦ = 5
H 2 (x,9) = -1 * (75 % 5 + 1) = -9 H(sepuluh) = ⎣17 * 0.036 ⎦ = 0
H 2 (x,10) = -1 * (102 % 5 + 1) = -30 Tabel ini tidak menunjukkan adanya collision.
Diktat : KBMI3305 - Struktur Data
Tabel 7.5. Penempatan probing
i Key H(x) H 2 (x) Penempatan probing H’(x) = H(x) + H 2 *(x,i)
10
Satu Dua Tiga Empat Lima Enam Tujuh Delapan Sembilan Sepuluh
Implementasi algoritma dengan bahasa pemrograman Pascal sebagai berikut : const bucket = 100; type paket = ^data;
data = record item : byte; next : paket;
end; var hash : array[1..99] of data; count : byte; head,current : paket; before, bil : hash;
{prosedur untuk memasukkan data dalam hash} procedure insert(x : byte; var nhash : hash); begin
count := nhash[x]; head := nhash[count] new(nhash[count]); nhash[count]^.item := x; nhash[count]^.next := head;
end;
function member(x : byte; var nhash : hash): boolean; begin
count := x mod bucket; if (count = bucket-1) then member := -1 else if nhash[count] = x then member := true else member := member(count+1);
Sepuluh Dua
Sembilan Enam Tujuh
Lima Saturday Delapan
16 Gambar 7.5. Rehashing
Diktat : KBMI3305 - Struktur Data
end; before := nhash[count]; current := nhash[count]^.next;
{prosedur untuk mencari data dalam while (before^.lagi <> nil ) and hash}
(not selesai) do procedure search(x : byte; var nhash :
begin
hash); if current^.isi = x then begin
begin
count := 0; before^.lagi := current^.lagi; if not member(x,bil) then
dispose(current); writeln(‘data tidak ada dalam hash’)
selesai := true else
end else
writeln(‘data pada posisi : ’, count);
begin
end; before := current; { prosedur menghapus data dari hash }
current := current^.next procedure delete(x : byte; var nhash :
var selesai : boolean;
selesai := true; count := nhash(x);
procedure hapus(x : byte; nhash : hash); if nhash[count]^.isi = x then
begin
begin if member(x, bil) then current := nhash[count];
begin
nhash[count] :=
delete(x, bil);
nhash[count]^.next; writeln(‘data telah dihapus’) dispose(current)
end else
end else writeln(‘data telah dihapus’); begin
end;
VII.4. KOMPRESI
Kompresi adalah suatu metode penghematan penyimpanan file dalam suatu media simpan. Dalam mengkompresi suatu file ada banyak metode-metode yang dapat digunakan dan salah satu yang akan dibahas adalah Algoritma Huffman.
Algoritma Huffman dipakai untuk mengkonstruksi kode prefix yang optimal, yang memiliki proses penggabungan yang berulang-ulang terhadap bobot dua item data yang terendah. Misalnya w1 dan w2 dua buah data yang berbobot paling kecil diantara w1, w2, w3, …, wn maka akan dibentuk tree w1+w2, w3, w4, …, wn sehingga w1+w2 akan membentuk subtree sebagai berikut :
W1 W2
Gambar 7.6. Pembentukan subtree pohon Huffman
Diktat : KBMI3305 - Struktur Data
Dengan cara yang sama untuk semua data dapat dibentuk sub-sub tree sampai akhirnya membentuk sebuah pohon Huffman.
Contoh :
Tabel 7.6. Data pohon Huffman Karakter
Frekwensi
Total Bit
Langkah-langkah pembentukan pohon Huffman sebagai berikut : 1)
2) dipilih 2 buah elemen data yang terkecil yaitu s dan nl dengan jumlah 4 dengan membentuk subtree T1
3) Kemudian dua buah elemen data lainnya dibandingkan untuk membentuk subtree
berikutnya yaitu T1 dan t
8 T2
T1
sp
nl
Diktat : KBMI3305 - Struktur Data
4) Demikian seterusnya sampai terbentuk pohon Huffman yang komplit
5) Perhatikan bahwa e=15, I=12, sp=13, dan t3=18 maka yang digabung adalah I dan sp
6) Menggabung e dengan T3 sebagai berikut :
33 T5
T3
T2
25 4 T1
T4
sp
nl
Diktat : KBMI3305 - Struktur Data
7) Akhirnya diperoleh bentuk komplit pohon Huffman sebagai berikut :
Gambar 7.7. Proses pembentukan pohon Huffman
Syarat pemberian nilai digit pada cabang kiri bernilai 0 dan cabang kanan bernilai 1 Berdasarkan pohon Huffman yang terbentuk (Gambar 7.7) maka dapat dicatat coding untuk masing-masing karakter, sebagai berikut :
Tabel 7.7. Kode Karakter Karakter Code
s 00000 t
nl 00001 Kemudian fase untuk decoding dapat dibentuk seperti diperlihatkan pada tabel berikut ini
Tabel 7.8. Proses Decoding indeks
Parent
Char Bobot
(ayah)
Tipe
anak
0 a 10 9 1
1 e 15 11 1
5 sp
6 nl
7 T1
8 T2
Diktat : KBMI3305 - Struktur Data
Berikut implementasi algoritma dengan bahasa pemrograman pascal : uses crt, printer, dos;
begin
const N = 4096; F = 18; outbufptr := bufsize; limit = 2;
inbufptr : word = bufsize;
end;
inbufsize : word = bufsize; outbufsize : word = 0;
(* prosedur inisialisasi BST *) outbufsize : word = 0;
procedure inittree;
var infile, outfile : file;
var i : word;
height, posmatch, lengthmatch, lengthend :
textbuf : array [0..n + F –2] of byte;
repeat
left, mom : array[0..n] of word;
right[i] := nul;
right : array[0..n+256] of word;
inc(i);
codebuf : array[0..16] of byte;
until (i>N+256);
beof, press : boolean;
i := 0;
h1, h2, m1, m2, s1, s2, c1, c2 : word;
repeat
mom[i] := nul;
(* fungsi untuk membaca karakter *)
inc(i);
function readchar : byte;
until (i=n)
begin
end;
readchar := 0; if inbufptr >= inbufsize then
(* prosedur menggeser posisi node keatas *) begin
prosedur shifted(me : word); blockread(infile, inbuf, bufsize, inbufsize);
var ancestor, grdmtr, mother, child, brother : inbufptr := 0
word;
end;
bexit : boolean;
if inbufsize = 0 then beof := true else
begin
begin
bexit := false;
beof := false;
repeat
readchar := inbuf[inbufptr]; mother := mom[me]; inc(inbufptr);
(* jika ibu bukan spesial node *) end
if mother <= nul then end;
begin
grdmtr := mom[mother]; (* prosedur menulis buffer ke file output *)
(* jika ibu bukan spesial node *) procedure printfile;
if grdmtr <= nul then var actual : word;
begin
begin ancestor := mom[grdmtr]; blockwrite(outfile, outbuf, outbufptr, actual)
(* jika aku anak kiri dari ibu *) end;
if left[mother] = me then
begin
(* prosedur menulis karakter ke buffer output *) (* jika ibu anak kiri dari nenek *) procedure printchar(nchar : byte);
if left[grdmtr] = mother then begin
begin
outbuf[outbufptr] := nchar; brother := right[mother]; inc(outbufptr);
left[grdmtr] := brother; if outbufptr >= bufsize then
mom[brother] := grdmtr;
Diktat : KBMI3305 - Struktur Data
child := right[me];
end else
left[mother] := child;
(* jika nenek spesial node *)
mom[child] := mother;
begin
right[mother] := grdmtr;
(* apakah aku merupakan anak kiri *)
right[me] := mother;
if left[mother] = me then
mom[grdmtr] := mother;
begin
mom[mother] := me
child := right[me];
end else
left[mother] := child;
(* ibu anak kanan dari nenek *)
right[me] := mother
begin
end else
child := left[me];
begin
right[grdmtr] := child;
child := left[me];
mom[child] := grdmtr;
right[mother] := child;
child := right[me];
left[me] := mother
left[mother] := child;
end;
mom[child] := mother;
right[grdmtr] := me;
left[me] := grdmtr;
mom[child] := mother;
right[me] := mother;
mom[me] := grdmtr;
mom[mother] := me;
mom[mother] := child;
mom[grdmtr] := me
bexit := true
end
end
end else
end else
(* aku anak kanan dari ibu *)
bexit := true;
begin
until bexit;
(* ibu anak kiri dari nenek *)
end;
if left[grdmtr] = mother then
begin
(* prosedur untuk menambah node baru *)
child := right[me];
procedure addnode(position : word0;
left[grdmtr] := child;
var preposition, templen, child : word;
mom[child] := grdmtr;
trigg : integer;
child := left[me];
bexit : boolean;
right[mother] := child;
begin
mom[child] := mother;
trigg := 1;
right[me] := grdmtr;
lengthmatch := 0;
left[me] := mother;
height := 0;
mom[mother] := me;
preposition := textbuf[position] + n + 1;
mom[grdmtr] := me
right[position] := nul;
end else
left[position] := nul;
(* ibu anak kanan dari nenek *)
bexit := false;
begin
repeat
brother := left[mother];
inc(height);
right[grdmtr] := brother;
if trigg > 0 then
mom[brother] := grdmtr;
(* untuk node dikanan *)
child := left[me];
begin
right[mother] := child;
if right[preposition] = nul then
mom[child] := mother;
(* ditambah jika node sebelum kosong *)
left[mother] := grdmtr;
begin
left[me] := mother;
right[preposition] := position;
mom[mother] := me;
mom[position] := preposition;
mom[grdmtr] := mother
bexit := true
end
end else
end; preposition := right[preposition] if (ancestor > nul) or
end else
(right[ancestor] = grdmtr) then
(* tambah node di kiri *)
right[ancestor] := me
begin
else left[ancestor] := me; if left[preposition] = nul then mom[me] := ancestor
(* tambah, jika node sebelumnya null *)
Diktat : KBMI3305 - Struktur Data
begin
begin
left[preposition] := position; while right[descend] <> nul do mom[position] := preposition;
descend := right[descend]; bexit := true
right[mom[descend]] := end else
left[descend]; preposition := left[preposition]
mom[left[descend]] := end;
mom[descend]; if not bexit then
left[descend] := left[me]; begin
mom[left[me]] := descend; templen := 1;
child := descend repeat
end;
trigg := textbuf[position + templen] – right[child] := right[me];
mom[right[me]] := child if trigg = 0 then inc(templen)
textbuf[preposition + templen];
end else child := right[me]; until (trigg <> 0) or (templen >= F);
end else child := left[me]; if templen > lengthmatch then
mom[child] := mother; begin
if right[mother] = me then posmatch := preposition;
right[mother] = child lengthmatch := templen;
else left[mother] := child; if templen .= f then
mom[me] := nul
begin
end
mom[position] := mom[preposition];
end;
child := left[preposition]; left[position] := child;
(* prosedur untuk mengkoding file *) mom[child] := position;
procedure encode;
child := right[preposition]; var temp, ptrcodebuf, cycleencode. right[position] := child;
Nchar, totread : byte; mom[child] := position;
ptrinsert, ptrencode : word; (* jika preposisi anak kanan ibunya *)
bexit : boolean;
if right[mom[preposition]] =
begin
preposition then inittree; temp := 0; right[mom[preposition]] := position
codebuf[0] := 0; ptrcodebuf := 1; else
cycleencode := 1; ptrinsert := 0; left[mom[preposition]] := position;
ptrencode := N – F; bexit := false; mom[preposition] := nul;
repeat
bexit := true
nchar := readchar;
end;
if not beof then
end;
begin
end; textbuf[ptrencode + temp] := nchar; until bexit;
inc(temp)
if height >=30 then shifted(position)
end;
end; until (temp >= f) or (beof); if temp > 0 then
(* prosedur untuk menghapus node *)
begin
procedure erasenode(me : word);
totread := temp;
var mother, child, descend : word; addnode(ptrencode); begin
repeat
mother := mom[me]; if lengthmatch > totread then if mother <> nul then
lengthmatch := totread; begin
if lengthmatch <= limit then if right[me] <> nul then
begin
begin lengthmatch := 1; child := left[me];
codebuf[0] := codebuf[0] or if left[me] <> nul then
cycleencode; begin
codebuf[ptrcodebuf] := descend := right[child];
textbuf[ptrencode]; if descend <> nul then
inc(ptrcodebuf]
Diktat : KBMI3305 - Struktur Data
end else
inc(temp)
begin until temp >= ptrcodebuf codebuf[ptrcodebuf] := posmatch and
end;
bexit := true
inc(ptrcodebuf)
end
codebuf[ptrcodebuf] :=
until bexit
(posmatch and 65280) shr 4 +
end
lengthmatch – (limit + 1);
end;
inc(ptrcodebuf) end;
(* prosedur mendekoding *) cycleencode := cycleencode shl 1;
procedure decode;
if cycleencode = 0 then var temp, headerbyte, nchar, cycledecode, begin
prefixbit : byte;
temp := 0; ptrtextbuf : word; bexit : boolean; repeat
begin
printchar(codebuf[temp]); cycledecode := 0; ptrtextbuf := N - F; inc(temp)
bexit := false;
until temp >= ptrcodebuf;
repeat
ptrcodebuf := 1; cycleencode := 1; cycledecode := cycledecode shr 1; codebuf[ 0] := 0
if cycledecode = then then end;
begin
temp := 0; lengthakhit := lengthmatch; nchar := readchar; repeat
if beof then
nchar := readchar; bexit := true else if not beof then
begin
begin cycledecode := 255; erasenode(ptrinsert);
headerbyte := nchar textbuf[ptrinsert] := nchar;
end
if ptrinsert < (F-1) then
end
textbuf[ptrinsert + N] := nchar;
if not bexit then
inc(ptrinsert);
begin
ptrinsert := ptrinsert and (N-1); prefixbit := headerbyte and 1; inc(ptrencode);
headerbyte := headerbyte shr 1; ptrencode := ptrencode and (N-1);
if prefixbit = 1 then addnode(ptrencode);
begin
inc(temp) nchar := readchar; end
if beof then bexit := true else until (temp >= lengthend) or (beof);
begin
while temp < lengthend do textbuf[ptrtextbuf] := nchar; begin
inc(ptrtextbuf); inc(temp);
ptrtextbuf := ptrtextbuf and (N-1); erasenode(ptrinsert);
printchar(nchar) inc(ptrinsert);
end
ptrinsert := ptrinsert and (N-1);
end else
inc(ptrencode);
begin
ptrencode := ptrencode and (N-1); nchar := readchar; dec(totread);
if beof() then bexit := true else if totread > 0 then
begin
addnode(ptrencode0 temp := nchar; end;
nchar := readchar; if totread <= 0 then
if beof then bexit := true else begin
begin
if ptrcodebuf >= 1 then posmatch := nchar shr 4; begin
posmatch := (posmatch shl 8 ) temp := 0;
or temp; repeat
lengthmatch := nchar and 15) +
printchar(codebuf[temp]);
limit = 1;
Diktat : KBMI3305 - Struktur Data
repeat
writeln(‘Waktu proses =
posmatch := posmatch and
‘,processtime,’Detik’);
end; (N-1);
nchar := texbuf[posmatch]; textbuf [ptrtextbuf] := nchar;
(* program utama *)
inc(ptrtextbuf);
begin
ptrtextbuf := ptrtextbuf and
clrscr;
(N-1);
if (paramcount < 2) or (paramcount > 4) then
printchar(nchar);
begin
inc(posmatch);
writeln(‘ Sintak : ‘, paramstr(0),
dec(lengthmatch);
‘ Input file outfile[dekompresi]’);
until lengthmatch = 0
end if paramstr(1) = paramstr(2) then end
begin
end writeln(‘Nama file harus beda’); until bexit
halt
end;
end; assign(infile, paramstr(1));
procedure kompresi;
{$I--}
begin
reset(infile, 1);
inbufptr := bufsize; inbufsize := bufsize;
if ioresult <> 0 then
outbufptr := 0; height := 0;
begin
posmatch := 0; lengthmatch := 0; writeln(‘Salah input file ‘,paramstr(1)); lengthend := 0;
halt
fillchar(textbuf, sizeof(textbuf),0);
end;
fillchar(left, sizeof(left),0); assign(outfile, paramstr(2)); fillchar(mom, sizeof(mom),0);
rewrite(outfile, 1);
fillchar(right, sizeof(right),0);
{$I+}
fillchar(codebuf, sizeof(codebuf),0);
if ioresult <> 0 then
encode;
begin
printfile writeln(‘Salah output file ‘,paramstr(2)); end;
halt
end;
procedure dekompresi; gettime(h1, m1, s1, c10; begin
if paramcount <> 3 then inbufptr := bufsize; inbufsize := bufsize;
begin
outbufptr := 0;
press := true;
fillchar(textbuf, sizeof(textbuf),0);
kompresi
decode;
end else
press := false; dekompresi
procedure statistik;
end;
var cprocess : string[10]; gettime(h2, m2, s2, c2); processtime : word;
statistik;
begin
close(outfile);
processtime := (h2 * 3600 + m2 * 60 + s2) –
close(infile);
(h1 * 3600 + m1 * 60 + s1);
readln;
if press then
end.
cprocess := ‘Kompresi’ else cprocess := ‘Dekompresi’; writeln(‘Proses = ‘, cprocess); writeln(‘Input : ‘, paramstr(1):11, ‘ ‘:10,
filesize(infile)’); writeln(‘output : ‘, paramstr(2):11, ‘ ‘:10, filesize(outfile)’);
Diktat : KBMI3305 - Struktur Data
BAB VIII GRAPH
VIII.1. DEFENISI GRAPH
Suatu graph G=(V,E) berisi suatu himpunan vertex dan himpunan edge E, masing- masing edge adalah sepasang (v,w) dimana v,w ε V. Vertex sering disebut dengan node dan edge disebut dengan arc.
Beberapa himpunan vertex yang terhubung dengan himpunan edge akan membentuk graph. Jika sepasang edge diorder dan graph itu disebut dengan graph directed (digraph). Dalam digraph bahwa vertex w adalah adjacent (bersinggungan) terhadap vertex v jika dan hanya jika (iff) (v,w) ε E. Kadang-kadang edge memiliki komponen ketiga disebut weight (bobot) atau cost (ongkos).
Misalkan V = { v 0 ,v 1 ,v 2 ,v 3 ,v 4 ,v 5 ,v 6 } dengan 12 edge diperoleh :
(v 0 ,v 1 , 2) , (v 0 ,v 3 , 1) , (v 0 ,v 1 , 3) , (v 1 ,v 4 , 10)
⎨ (v E = 3 ,v 4 , 2) , (v 3 ,v 6 , 4) , (v 3 ,v 5 ,8 ), (v 3 ,v 2 , 2)
⎩ (v 2 ,v 0 , 4), (v 3 ,v 4 , 2),(v 4 ,v 6 , 6), (v 6 ,v 5 , 1) ⎭
Sehingga diperoleh graph terhubung (digraph) sebagai berikut :
V0 2 V1
4 1 3 Indegree v 3 = 2 ={v 0 ,v 1 }
Outdegree v3 = 4
V2 2 V3 2 V4 2 ,v = {v 4 ,v 5 ,v 6 }
5 6 V5 V6
Gambar 8.1. Graph berarah
Berdasarkan gambar diatas bahwa vertex yang adjacent terhadap v 3 adalah v 2 ,v 4 ,v 5 , v 6 dan |V| = 7 dan |E| = 12 dan |S| merepresentasikan size himpunan S Suatu path dalam graph adalah sikuensi dari vertex-vertex : w 1 ,w 2 , …, w n sedemikian sehingga (w i ,w i+1 ) ε E untuk 1<= i < n Length (panjang) dari suatu path adalah sejumlah node pada suatu path yaitu n-1, dan sering disebut dengan unweigted path length yaitu sejumlah biaya pada edge dalam path.
Misalnya : Path v 0 sampai v 5 adalah v 0 ,v 3 ,v 5. Panjang path adalah 2 edge dan weighted path
length adalah 9 yang kebetulan path terpendek antara v 0 dan v 5 . Simple path (path sederhana) adalah path yang mana semua vertex-vertex jelas, kecuali awal dan akhir boleh sama. Cycle dalam suatu digraph adalah suatu path dengan panjang paling sedikit 1 sedemikian sehingga w 1 =w n ; Suatu directed acycle graph (DAG) kadang-kadang didasarkan pada suatu penggabungan, dengan asumsi bahwa dalam directed graph (digraph = graph berarah) tidak boleh ada cycle.
Diktat : KBMI3305 - Struktur Data
VIII.2. SHORTEST PATH PROBLEM
Shortest path problem (SPP) merupakan proses menemukan path terpendek (diukur dari banyaknya edge) dari vertex ditandai dengan S terhadap semua vertex.
Gambar 8.2. Graph berarah SPP
SPP dapat diselesaikan dengan Algoritma Djikstra pada graph adjacent diats dari C ke E (undirected = tidak berarah).
{C} : {A, B, D, E } ≈ C – A = 581
C – B = 420 Minimum {C,D} = 162
C – D = 162
C – E = 921
{C,D} : {A, B, C} ≈
A = min {CA, CDA} = {581, 469}
B = min {CB, CDB} = {420, 343} Minimum {C,D,E} = 323
C = min {CE, CDE} = {921, 323}
Maka path terpendek dengan Algoritma Djikstra adalah {C,D.E} = 323 (total jarak} Contoh 2 :
Gambar 8.3. Graph berarah SPP lain
Cari SPP dari satu vertex ke seluruh vertex lain dengan Algoritma Djikstra,
A : inisialisasi A=0 yang lain ke n
B : semula n dari A : 0 + 50 = 50 ; berarti terpendek ke AB = 50
path terpendek
E : semula n adalah AB
Diktat : KBMI3305 - Struktur Data
dari A : 0 = 100 ; berarti terpendek ke AE = 100
C : semula n dari B : 50 + 30 = 80 ; berari terpendek ke ABC = 80
D : semula n path terpendek dari B : 50 + 40 = 90 ; berarti terpendek ke ABD = 90 adalah ABC
F : semula n dari E : 100+60 = 160; berarti terpendek ke AEF=160
D : semula 90 dari B dari C = 80 + 5 = 85
F : semula 160 dari E
tetap melalui E
dari D : 85 + 80 = 165
yaitu AEF = 160
G : semula n dari C = 80 + 200 = 280
melalui F
dari F = 160 + 40 = 200
yaitu AEFG = 200
jadi jalur terpendek dari :
A – B = 50 ≈ AB
A – C = 80 ≈ ABC
A – D = 85 ≈ ABCD
A – E = 100 ≈ AE
A – F = 160 ≈ AEF
A – G = 200 ≈ AEFG
VIII.3. ALGORITMA MINIMAL SPANNING TREE Minimal spanning tree (MST) sering digunakan untuk menyelesaikan suatu proyek, dimana pada algoritma ini mengenal dua metode yaitu PRIMS dan Kruskal. PRIMS adalah proses pengunjungan semua vertex yang dimulai dari salah satu vertex, dimana kunjungan hanya boleh dilakukan sekali terhadap satu node, sedangkan KRUSKAL adalah proses kunjungan dengan prims, hanya syaratnya tidak boleh siklus, dengan memulai dari edge terpendek kemudian dilanjutkan ke edge terpendek kedua dan seterusnya sampai semua vertex/node terkunjungi. Contoh :
KL
K - 215 581 307 353 L 215 - 420 181 413 M 581 420 - 162 921 N 307 181 162 - 161 P 353 413 921 161 -
Diktat : KBMI3305 - Struktur Data
a. PRIMS : K kunjungi = true; evaluasi K – L = 215
K – M = 581 Minimum = 215 K – N = 307
K – P = 353 L kunjungi = true; evaluasi K – M = 581 K – N = 307 K – P = 353
Minimum = 181 L – N = 181
L – P = 413
L – M = 420 N kunjungi = true; evaluasi K – M = 581 K – N = 307 K – P = 353 N – M = 162 Minimum = 161 N – P = 161
L – P = 413 L – M = 420
P kunjungi = true; evaluasi K – M = 581 K – N = 307
N – M = 162 P – M = 921 M kunjungi = true; evaluasi Stop karena semua vertex sudah dikunjungi (true) maka total MST PRIMS = 215 + 181 + 161 + 162 = 719 dan Himpunan pencarian adalah = {(K,L), (L,N), (N,P), (N,M)} maka bentuk tree dan graph dari proses MST ini sebagai berikut :
a. bentuk pohon PRIMS
b. Graph PRIMS
Gambar 8.4. Algoritma MST PRIMS
Diktat : KBMI3305 - Struktur Data
b. KRUSKAL Dari gambar 8.4.b. menunjukkan bahwa : K - L ≠ L–K
(N – P) = 161 ≈ { (N,P) } (N – M) = 162 ≈ { (N,P), (N,M) } (N – L) = 181 ≈ { (N,P), (N,M), (N,L) } (L – K) = 215 ≈ { (N,P), (N,M), (N,L), (L,K) }
Iterasi stop , karena setiap penambahan edge akan mengakibatkan proses penelusuran (trace) membentuk suatu siklus (cycle).
Jadi total MST Kruskal = (N,P) + (N,M) + (N,L) + (L,K)
= 161 + 162 + 181 + 215 = 719
Tree yang terbentuk sebagai berikut :
Gambar 8.5. Algoritma MST Kruskal
Diktat : KBMI3305 - Struktur Data
KEPUSTAKAAN
1. “Data structures and problem solving using java”; Mark Allen Weiss ; Addison Wesley ; 1998
2. “An Introduction to Data Structures and Algorithm with Java”; Gleen Rowe; Prentice Hall International Edition ; 1998
3. “Data Structures and Program Design” ; Robert L. Kruse ; Prentice Hall of India Privated Limited ; 1991
4. “Data Structures, Algorithms and Program Style Using C” ; James F. Korst; Leonard J. Garrett ; PWS-Kent Publishing Company ; 1988
5. “Data structures, Theory and Problem” ; Seymour Lipschutz ; McGraw Hill Book Company ; 1986
6. “Algorithms + Data Structures = Program” ; Niklaus Wirth ; Prentice Hall of India Private Limited; 1991
7. “Computer Algorithms, Introduction to Design and Analysis, Second Edition”, Sara Baase ; Addition – Wesley Publishing Company ; 1988
8. “Problem Solving and Structured Programming in Pascal, Second Edition”, Iliot B. Koffman ; Addition – Wesley Publishing Company ; 1985
9. “Turbo Pascal , Reference Manual”; Scotts Valley ; Borland International ; 1985
10. “Turbo Pascal , Jilid 1”; Jogianto H.M. ; Andi Offset Yogyakarta ; 1989
11. “Turbo Pascal , Jilid 2”; Jogianto H.M. ; Andi Offset Yogyakarta ; 1989
12. “Dasar-Dasar Pemrograman Pascal, Teori dan Program Terapan” ; Insap P. Santoso, Ir, M.Sc ; Andi Offset Yogyakarta ; 1987
13. “Belajar Sendiri Pemrograman Dengan Turbo Pascal 7.0” ; Ediman Lukito ; Elex Media Komputindo ; 1993
14. “Struktur Data (transparansi)” ; Universitas Bina Nusantara ; Jakarta ; 2001