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