1 Pertemuan 26 Teknik Hashing Matakuliah: T0016/Algoritma dan Pemrograman Tahun: 2005 Versi: versi 2
2 Learning Outcomes Pada akhir pertemuan ini, diharapkan mahasiswa akan mampu : Menjelaskan teknik hashing yang umum
3 Outline Materi Linear probing Double Hashing Separate Chaining
4 Linear probing Linear probing mencari alamat (lokasi) berikutnya secara linier sampai ditemukan lokasi yang belum digunakan. Misalnya data tambahan dengan nilai “26, James Gray, DB & trans processing “. Hash function memberikan nilai 3, yang ternyata telah ditempati data lain. Penelusuran mendapatkan lokasi kosong pada indeks 6 sehingga data ini ditempatkan pada [6]. Data tambahan lainnya dengan nilai ”54, Manuel Blum, Computational complexity “ di-hash ke alamat 54%3 = [8] yang telah diisi data. Penelusuran selanjutnya mendapat lokasi kosong pada [9].
5 SemulaMenjadi KodeNamaKodeNama [0] 46John McCarthy…46John McCarthy… [1] [2] 25Donald E. Knuth…25Donald E. Knuth… [3] 49CAR Hoare…49CAR Hoare… [4] 50Raj Reddy…50Raj Reddy… [5] 5John Hopcroft…5 … [6] 26James Gray… [7] 30Dennis M. Ritchie…30Dennis M. Ritchie… [8] 8Marvin Minsky…8 … [9] 54Manuel Blum… [10] 33Niklaus Wirth…33Niklaus Wirth… [11] [12] 35E.W. Dijkstra…35E.W. Dijkstra…
6 Modul-Modul Hashing Dengan Linear Probing int linearprobe(tHashtbl ht, int addr, int M) { while((ht.tabel[++addr].kode % M) != -1); return addr; } int buildhashtable(tHashtbl *ht, tHashrec a, int M) { int addr = hash(a.kode, M); if((*ht).tabel[addr].kode == a.kode) return 0; if((*ht).tabel[addr].kode != -1) addr = linearprobe(*ht, addr, M); (*ht).tabel[addr].kode = a.kode; strcpy((*ht).tabel[addr].nama, a.nama); strcpy((*ht).tabel[addr].kontrib, a.kontrib); return 1; } int search(tHashtbl ht, tHashrec *rec, int M, int key){ int addr = hash(key, M); if (ht.tabel[addr].kode == -1) return -1; while (ht.tabel[addr].kode != key) addr= (addr + 1) % M; (*rec).kode = ht.tabel[addr].kode; strcpy((*rec).nama, ht.tabel[addr].nama); strcpy((*rec).kontrib, ht.tabel[addr].kontrib); return 1; }
7 Function linearprobe( ) mengadakan penelusuran secara linier. Bila penelusuran telah mencapai posisi terakhir maka pindah ke posisi pertama (% M). Pada linear probing semua nilai kunci yang di- hash ke lokasi yang sama akan menjalani proses penelu-suran lokasi yang sama sampai ditemukan lokasi kosong, ini disebut primary clustering. Nilai kunci yang berbeda, misalnya 27 akan di-hash ke lokasi 4 yang telah ditempati.
8 Double Hasing Double hashing bertujuan untuk mengatasi primary clustering, terhadap nilai hash yang berbeda mestinya dilakukan pencarian lokasi kosong dengan pergeseran yagn berbeda. Metode ini menggunakan hash function kedua bila terjadi collision. Hash function kedua ini melibatkan nilai kunci, digunakan untuk mendapatkan jarak loncatan, tidak seperti linier probing yang loncat ke posisi berikutnya. Misalkan hash function kedua adalah 8 – (key %8). Terhadap data “26, James Gray, DB & trans processing “, dihitung hash2 (26) = 8 – (26 % 8) = 6. hash1(26) = 26 % 23 = 3; posisi 3 telah terisi maka lanjutkan perhitungan (3 + 6) % 23 = 9, posisi telah ditemukan Contoh lain misalnya akan ditambahkan data “54, Manuel Blum, Computational complexity”, dihitung hash2(54) = 8- (54 % 8) = 2 hash1(54) = 54 % 23 = 8 ; posisi 8 telah terisi maka lanjutkan perhitungan (8 + 2) % 23 = 10, posisi telah terisi (10+2) % 23 = 12, posisi telah terisi (12+2) % 23 = 14, posisi ditemukan
9 SemulaMenjadi KodeNamaKodeNama [0] 46John McCarthy…46John McCarthy… [1] [2] 25Donald E. Knuth…25Donald E. Knuth… [3] 49C.A.R. Hoare…49C.A.R. Hoare… [4] 50Raj Reddy…50Raj Reddy… [5] 5John Hopcroft…5 … [6] [7] 30Dennis M. Ritchie…30Dennis M. Ritchie… [8] 8Marvin Minsky…8 … [9] 26James Gray… [10] 33Niklaus Wirth…33Niklaus Wirth… [11] [12] 35E.W. Dijkstra…35E.W. Dijkstra… [13] [14] 54Manuel Blum… [15] 61Richard Hamming…61Richard Hamming…
10 Modul-Modul Hashing Dengan Double Hashing int hash2(int n) { return (8 - (n % 8)); } int doublehash(tHashtbl ht, int addr, int u, int M) { while((ht.tabel[addr+=u].kode % M) != -1); return addr; } int buildhashtable(tHashtbl *ht, tHashrec a, int M) { int addr = hash(a.kode, M), step; if ((*ht).tabel[addr].kode == a.kode) return 0; if ((*ht).tabel[addr].kode != -1) { step = hash2(a.kode); addr = doublehash(*ht, addr, step, M); } (*ht).tabel[addr].kode = a.kode; strcpy((*ht).tabel[addr].nama, a.nama); strcpy((*ht).tabel[addr].kontrib, a.kontrib); return 1; } int search(tHashtbl ht, tHashrec *rec, int M, int key){ int addr = hash(key, M); int step = hash2(key); if (ht.tabel[addr].kode == -1) return -1; while (ht.tabel[addr].kode != key) addr= (addr+step ) % M; (*rec).kode = ht.tabel[addr].kode; strcpy((*rec).nama, ht.tabel[addr].nama); strcpy((*rec).kontrib, ht.tabel[addr].kontrib); return 1; }
11 Separate Chaining Pada separate chaining data ditampung dalam array of pointer. Masng-masing pointer akan menunjuk ke linked list sehingga tidak akan menimbulkan collision. Kunci yang memiliki nilai hashing yang sama disimpan pada satu linked link yang sama.
12
13 Modul-Modul Hashing Dengan Separate Chaining # include struct thashrec { int kode; char nama[21]; char kontrib [41]; } ; typedef struct thashrec tHashrec; struct thashlink { tHashrec data; struct thashlink *next; } ; typedef struct thashlink tHashlink; struct thashtbl { tHashlink * tabel[23]; } ; typedef struct thashtbl tHashtbl; void inithashtable(tHashtbl *ht, int M) { for (int i = 0; i < M; i++) (*ht).tabel[i] = NULL; } int hash(int n, int M) { return (n % M); }
14 void buildhashtable(tHashtbl *ht, tHashrec a, int M) { int addr = hash(a.kode, M); tHashlink *node, *curr; node = (tHashlink *) malloc (sizeof(tHashlink)); node->data.kode = a.kode; strcpy(node->data.nama, a.nama); strcpy(node->data.kontrib, a.kontrib); node->next= NULL; curr = (*ht).tabel[addr]; if (curr == NULL) (*ht).tabel[addr] = node; else { while(curr->next!= NULL) curr= curr-> next; curr->next= node; } int search(tHashtbl ht, tHashrec *a, int kunci, int M) { int addr = hash(kunci, M); tHashlink *curr; if (ht.tabel[addr] == NULL) return 0; curr = ht.tabel[addr]; while (curr != NULL) { if (curr->data.kode == kunci) { (*a).kode= curr->data.kode; strcpy((*a).nama, curr->data.nama); strcpy((*a).kontrib, curr->data.kontrib); return 1; } curr = curr->next; } return 1; }
15 Pada modul inithashtable()parameter foraml berupa array of linked-list yang berfungsi sebagai hash table. Seluruh elemen array diberi nilai awal NULL. Hash table dikirim ke modul buildhashtable( ) untuk ditambahkan satu simpul. Data yang akan ditambahkan berada pada record a. Fungsi hash() menghitung posisi addr berdasarkan nilai field kode pada record a. Satu simpul baru dibentuk dan diacu oleh node. Data baru disalin ke node dan selanjutnya node dikaitkan pada hash table posisi addr. Untuk mengaitkan node ke hash table posisi addr maka perlu memeriksa keberadaan linked list pada posisi ini, apakah sudah terbentuk atau belum.
16 Jika linked list pada posisi ini belum terbentuk (ditandai dengan curr == NULL) maka alamat node menjadi alamat posisi addr hash table. Apabila linked list telah terbentuk maka pointer curr mencari ujung linked list lalu menyambungnya ke node. Modul search( ) mencari simpul pada hash table yang mengandung kunci yang dicari, dimulai dengan memanggil hash function untuk mengetahui posisi atau addr. Linked list pada posisi addr ditelusuri sampai kunci ditemukan atau telah mencapai NULL.