Searching Pertemuan ke 15.
Searching Searching adalah pencarian data tertentu didalam sekumpulan data berdasarkan key tertentu. Kumpulan data tempat pencarian bisa dalam keadaan terurut (sorted) atau tidak terurut (unsorted). Algoritma searching: Sequential (sorted & unsorted) Binary (sorted) Interpolation (sorted) Indexing (file index sorted) Hashing (peletakan record pada tempat tertentu)
Searching: Sequential Sequential : proses pencarian data secara berurutan MULAI record pertama, satu per satu SAMPAI record dengan kunci yang sesuai ditemukan ATAU record terakhir namun kunci tidak sesuai (data dengan kunci yang sesuai kunci tidak ditemukan). Dalam sequential search, kumpulan data yang hendak dicari data kuncinya bisa dalam keadaan tidak terurut maupun terurut. NIP Nama Salary [0] 0101900948 Sucipto 26500000 [1] 0293899389 Nagasari 80000000 [2] 3930988399 Benjamin 20000000 [3] 8383839938 Suparman 10000000 Pada tabel diatas, Nomor Induk Pegawai (NIP) adalah key. Misalnya akan dicari data pegawai dengan NIP “3930988399”. Proses : Baca record pertama dan bandingkan antara field NIP, berisi “0101900948” dengan “3930988399”. Tidak cocok. Baca record kedua dan bandingkan antara field NIP, berisi “0293899389” dengan “3930988399”. Tidak cocok. Baca record ketiga dan bandingkan antara field NIP, berisi “3930988399” dengan “3930988399”. COCOK. (informasi nama pegawai dan salary bisa diproses).
Searching: Sequential 1 typedef char tkey[11]; 2 typedef struct trecord{ 3 tkey key; 4 char nama[21]; 5 float salary; 6 }; 7 int sequentialsearch(trecord arr[],int n,tkey key) { 8 int i; 9 for(i = 0; i < n; i++) 10 if(strcmp(key, arr[i].key)==0) return i; 11 return -1; 12 } Keterangan : - baris 10, mengembalikan indek ke i jika data ditemukan - Baris 11, mengembalikan -1 jika data tidak ditemukan
Searching: Binary Search Binary search adalah pencarian data berdasarkan key dimana pencarian data dimulai dari posisi tengah kumpulan data. Jika key yang dicari < key pada record ditengah, maka pencarian dengan cara yang sama dilakukan pada kumpulan data paruh atas (karena record yang dicari tidak mungkin berada di paruh bawah). Jika key yang dicari > key pada record ditengah, maka pencarian dengan cara yang sama dilakukan pada kumpulan data paruh bawah (karena record yang dicari tidak mungkin berada di paruh atas) Jika key yang dicari = key pada record ditengah, maka dikembalikan posisi (index) record ditengah, proses pencarian berhenti. Algorima ini lebih efisien daripada sequential search karena lingkup pencarian selalu setengah setiap kalinya. Apa yang terjadi jika binary search digunakan untuk mencari record tertentu pada sekumpulan data yang belum terurut berdasarkan key tertentu ?
Searching: Binary Search (data ketemu) Tabel dibawah telah terurut berdasarkan Nomor Induk Pegawai (NIP) sebagai key. Misalkan dicari record dengan key “0101900951”. NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000
Searching: Binary Search (data ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Mid High low=0 ; high=n-1=6; mid=(6+0)/2=3. array[mid].NIP = “0101900920” < key mungkin record ada di paruh bawah. Ubah low = mid+1=4 Key = “0101900951”
Searching: Binary Search (data ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Mid High low=4 ; high = 6 ; mid = (6+4)/2=5 array[mid].NIP = “0101900951” = key record ditemukan Key = “0101900951”
Searching: Binary Search (data tidak ketemu) Dalam binary search jika low > high berarti data tidak ditemukan didalam kumpulan data tersebut. Jadi pada kondisi ini pencarian dihentikan. Tabel dibawah telah terurut berdasarkan Nomor Induk Pegawai (NIP) sebagai key. Misalkan dicari record dengan key “0101900952”. NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000
Searching: Binary Search (data tidak ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Mid High low=0 ; high=n-1=6; mid=(6+0)/2=3 array[mid].NIP = “0101900920” < key mungkin record ada di paruh bawah. Ubah low = mid+1=4 Key = “0101900952”
Searching: Binary Search (data tidak ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Mid High low=4 ; high = 6 ; mid = (6+4)/2=5 array[mid].NIP = “0101900951” < key mungkin record ada di paruh bawah. Ubah low = mid+1=6 Key = “0101900952”
Searching: Binary Search (data tidak ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 High Low Mid low=6 ; high = 6 ; mid = (6+6)/2=6 array[mid].NIP = “0101900979” > key mungkin record ada di paruh atas. Ubah high = mid-1=5 Key = “0101900952”
Searching: Binary Search (data tidak ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 High Low Mid Key = “0101900952” low=6 ; high = 5 ; Low > High, maka pencarian dihentikan, data tidak ditemukan
Searching: Binary Search 1 typedef char tkey[11]; 2 typedef struct trecord{ 3 tkey key; 4 char nama[21]; 5 float salary; 6 }; 7 int binarysearch(trecord arr[],int n,tkey key) { 8 int mid,low,high; 9 low = 0; 10 high = n – 1; 11 while( low <= high ) { 12 mid = (low + high) / 2; 13 if(strcmp(key,arr[mid].key) == 0) return mid; 14 if(strcmp(key,arr[mid].key) < 0) high = mid - 1; 15 else low = mid + 1; 16 } 17 return -1; 18 }
Searching: Interpolation search Interpolation search pada dasarnya hampir sama dengan binary search , tetapi jika binary search kumpulan datanya dibagi menjadi 2 untuk mendapatkan posisi tengah (mid), pada interpolation pembagian itu diusahakan sedekat mungkin dengan data yang akan dicari. Analogi interpolation search adalah pencarian nomor telepon berdasarkan nama. Jika nama yang dicari “Willy”, maka akan lebih cepat dicari pada bagian akhir buku telepon, karena huruf ‘W’ adalah 4 huruf dari akhir buku telepon (posisi relatif kunci) . Tentu saja kumpulan data harus sudah dalam keadaan terurut sorted. Untuk menghitung posisi relatif kunci digunakan rumus sebagai berikut: kunci – data[low].key Posisi = ------------------------------------------ x (high – low) + low data[high].key – data[low].key
Searching: Interpolation search (data ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Posisi High low = 0 ; high = 6 ; data[low].key = “0101900900” ; data[high].key = “0101900979” 0101900951 - 0101900900 Posisi relatif = --------------------------------------------- x ( 6 – 0) + 0 = 3 (floor) 0101900979 - 0101900900 Karena data[3] .NIP= “0101900920”<key, maka record yang dicari mungkin berada di ‘bawah’, jadi ubah low = posisi+1 Key = “0101900951”
Searching: Interpolation search (data ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Posisi High Low = 4; High = 6 0101900951 - 0101900935 Posisi relatif = --------------------------------------- x (6-4) + 4 = 4 0101900979 – 0101900935 Karena data[4] .NIP=“0101900935”<key, maka record yang dicari mungkin berada di ‘bawah’, jadi ubah low = posisi+1 Key = “0101900951”
Searching: Interpolation search (data ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Posisi High Low = 5 ; High = 6 0101900951 - 0101900951 Posisi relatif = -------------------------------------- x (6-5) + 5 = 5 0101900979 – 0101900951 Karena data[5] .NIP=“0101900951”=key .Record ditemukan pada posisi data[5] Key = “0101900951”
Searching: Interpolation search (data tidak ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Posisi High low = 0 ; high = 6 ; data[low].key = 0101900900 ; data[high].key = 0101900979 0101900952 - 0101900900 Posisi relatif = ------------------------------------ x ( 6 – 0) + 0 = 3 (floor) 0101900979 – 0101900900 Karena data[3] .NIP= “0101900920”<key, maka record yang dicari mungkin berada di ‘bawah’, jadi ubah low = posisi+1 Key = “0101900952”
Searching: Interpolation search (data tidak ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Posisi High Low = 4; High = 6 ; 0101900952 - 0101900935 Posisi relatif = --------------------------------------- x (6-4) + 4 = 4 0101900979 – 0101900935 Karena data[4] .NIP=“0101900935”<key, maka record yang dicari mungkin berada di ‘bawah’, jadi ubah low = posisi+1 Key = “0101900952”
Searching: Interpolation search (data tidak ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 Low Posisi High Low = 5; high = 6 ; 0101900952 - 0101900951 Posisi relatif = --------------------------------------- x (6 – 5) + 5 = 5 0101900979 – 0101900951 Karena data[5] .NIP=“0101900951”<key, maka record yang dicari mungkin berada di ‘bawah’, jadi ubah low = posisi+1 Key = “0101900952”
Searching: Interpolation search (data tidak ketemu) NIP Nama Salary [0] 0101900900 Sucipto 26500000 [1] 0101900905 Nagasari 80000000 [2] 0101900913 Benjamin 20000000 [3] 0101900920 Suparman 10000000 [4] 0101900935 Suparmin 40000000 [5] 0101900951 Suhendra [6] 0101900979 Sumitro 30000000 High Low Key = “0101900952” Low = 6 ; high = 6 . Proses diulang terus “selama data[low].key <=key<=data[high].key”. Jika tidak terpenuhi, proses akan di hentikan dan data tidak akan ketemu. Karena data[low].NIP <=“0101900952”<=data[high].NIP,tidak terpenuhi maka data tidak ketemu
Searching: Interpolation search 1 typedef char tkey[11]; 2 typedef struct trecord{ 3 int key; 4 char nama[21]; 5 float salary; 6 }; 7 int interpolationsearch(trecord arr[],int n,int key) { 8 int low, high, pos ; 9 low = 0; high = n – 1; 10 do { 11 pos=(key–arr[low].key)*(high–low)/(arr[high].key–arr[low].key)+low; 12 if (arr[pos].key == key) return pos; 13 if (arr[pos].key > key ) high = pos – 1; 14 if (arr[pos].key < key ) low = pos + 1; 15 } while (key >= arr[low].key && key <= arr[high].key) 16 return -1; 17 }
Searching: Indexing Indexing identik dengan index yang biasanya ada dihalaman akhir buku. Jika ingin mencari key tertentu, bisa dilihat index untuk key yang akan dicari. Jika key ditemukan dibagian index, akan didapatkan informasi berupa nomor halaman yang berisi key yang dicari. Dalam contoh ini, buku adalah kumpulan data, halaman daftar index adalah index filenya. Jadi pada teknik indexing, akan melibatkan file kumpulan data dan akan dibuatkan satu atau lebih file index yang berisi daftar posisi record. Contoh : Dalam database design biasanya dibagi menjadi tabel - tabel menjadi table transaksi dan table master. Tabel Transaksi: misalnya transaksi penjualan yang terdiri dari field: kdbrg, qty , total Tabel Master : misalnya master barang yang terdiri dari field: kdbrg, nmbrg, hrgsatuan
Searching: File Index Mengapa diperlukan pemisahan tabel transaksi dan master ? Untuk efisiensi space dalam penyimpanan file, contohnya tidak perlu menyimpan namabarang didalam file transaksi cukup menyimpan kodebarang saja. Dengan mengetahui kodebarang, akan diketahui informasi yang lain untuk kodebarang tersebut,misalnya namabarang, hargabarang. Tabel master dan transaksi, sebaiknya diurutkan (sort) dahulu, agar proses pencarian (search) lebih cepat. Pengurutan record data (Sorting) terhadap kumpulan data berdasarkan key tertentu, memerlukan proses penempatan ulang semua field (TIDAK HANYA field KEY-nya saja). Proses penempatan ulang field-field memerlukan waktu tambahan. Bagaimana jika field dalam sebuah record berjumlah puluhan atau ratusan ? Untuk mengatasi problem diatas digunakan “file index”
File Master Barang (msbrg.dat) File Index Master Barang (msbrg.idx) Searching: File Index File Index : berisi informasi yang diperlukan saja untuk mengakses kumpulan data. Dengan file index, kumpulan data tidak perlu diurutkan. Cukup file index saja yang perlu diurutkan File Master Barang (msbrg.dat) File Index Master Barang (msbrg.idx) recno kodebarang Nama barang harga 1 00005 Sepatu 1000 2 00001 Sandal 3000 3 00002 Kaos 1500 4 00006 Sarung 4500 5 00004 Buku 6 00003 Tas 3500 7 00007 Kompor 9000 8 00009 Korek 7000 9 00010 Gas 10 00008 Tabung 8000 Recno.idx kodebarang Recno.dat 1 00001 2 00002 3 00003 6 4 00004 5 00005 00006 7 00007 8 00008 10 9 00009 00010
File Master Barang (msbrg.dat) File Index Master Barang (msbrg.idx) Searching: File Index File Master Barang (msbrg.dat) File Index Master Barang (msbrg.idx) recno kodebarang Nama barang harga 1 00005 Sepatu 1000 2 00001 Sandal 3000 3 00002 Kaos 1500 4 00006 Sarung 4500 5 00004 Buku 6 00003 Tas 3500 7 00007 Kompor 9000 8 00009 Korek 7000 9 00010 Gas 10 00008 Tabung 8000 Recno.idx kodebarang Recno.dat 1 00001 2 00002 3 00003 6 4 00004 5 00005 00006 7 00007 8 00008 10 9 00009 00010 file index berisi recno dari idx sendiri kemudian recno dari dat dan juga key yang akan dipakai untuk pencarian (kodebarang). Di file index kodebarang diurutkan. Cara pencarian data, baca file index dulu berdasarkan keynya misalnya cari kode barang 00006, setelah ketemu lihat recno.dat nya (4) berdasarkan recno.dat (4) ini cari ke kumpulan data (msbrg.dat).
Searching: File Index Program pembuatan file index bisa dilihat di hal 309 buku pengantar algoritma. Hal penting tentang file index: Tujuan file index ini adalah mempercepat pencarian, untuk itu saat pembentukan file index gunakan fwrite() sehingga memungkinkan pengaksesan secara random dengan fseek(), fread(). Jika file index berisi data sangat banyak maka perlu dibuat file index bertingkat. File index ke 1 berisi data range dari key yang akan dicari di file index ke 2. file index ke 2 ini berisi sejumlah record yang sama dengan record yang ada di kumpulan data.
Searching: File Index Misalkan mencari data H0123, maka baca di index1.idx dahulu. HO123, berada antara record 6485 dan 7377, kemudian cari secara binary di index2.idx dengan low = 6485 dan high = 7377. Cara ini lebih cepat daripada mencari dari index low = 0 (tanpa index bertingkat).
Searching: Hashing Algoritma Hashing mengatasi kelemahan binary maupun interpolation search. Walaupun kedua algoritma tersebut sudah cukup cepat, tapi memiliki kelemahan yaitu data harus diurutkan. Dengan Hashing, data tidak perlu diurutkan dan memungkinkan dalam satu kali pencarian langsung menemukan record yang diinginkan O(1). Hashing bertujuan untuk mendapatkan posisi (lokasi, alamat) record secara langsung( immediate, direct) pada saat dicari. Untuk itu record harus disimpan pada lokasi tertentu berdasarkan key record tersebut. Fungsi untuk mengubah key record menjadi posisi record untuk menyimpan atau membaca record disebut HASHING FUNCTION. Hash(Key) = posisi
Searching: Hashing
Searching: Hashing Function Hashing Function yang baik harus: Perhitungannya cepat Menghasilkan nilai posisi yang bisa terdistribusi rata (untuk menghindari tabrakan/collission). Beberapa cara menentukan Hashing Function: Digit Selection Division Multiplication Folding Character-valued key Perfect Hashing Function
Hashing: Digit selection Hashing function ini menentukan nilai hash dengan memilih beberapa digit dari nilai kunci. Contoh : Key=d1d2d3d4d5d6d7d8d9 d1 = kode fakultas ; d2=kode jurusan; d3=kode program studi; d4d5=tahun masuk; d6d7d8d9=urutan registrasi mahasiswa; Misalkan dipilih digit d7d8d9 , maka Hash(Key) = key mod 1000 Misalkan dipilih digit d1d2d6d7d8d9 akan memberikan hasil yang baik dalam arti nilai hash terdistribusi merata. Misalkan dipilih digit d1d3d5 , hash function ini kurang tepat karena akan banyak data yang memberikan nilai hash yang sama( nilai hash tidak terdistribusi dengan merata).
Hashing: Division Hashing function ini menentukan nilai hash dengan membagi nilai kunci dengan nilai tertentu Contoh : Hash(key) = key mod m = h , Sehingga 0 <= h <= m -1 Aturan umum dalam pemilihan m adalah dengan memakai bilangan prima. Misalkan data 1100,1200,1300,1400,1500 Jika dipilih m = 100, maka hash function akan menghasilkan 0 untuk kelima data key diatas. Jika dipilih m =97 (bilangan prima), maka data tersebut akan dihash kelima alamat yang berbeda yaitu: 33,36,39,42,45 .
Hashing : Multiplication Dengan cara ini, dilakukan perkalian tehadap bilangan itu sendiri. Hasilnya akan membentuk bilangan yang cukup besar, kemudian lakukan seleksi angka. Misalkan key terdiri dari 5 angka maka perkaliannya membentuk 10 angka. Key = d1d2d3d4d5 Multiply (d1d2d3d4d5, d1d2d3d4d5) = r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 Hash(key) = select( r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 ) Pada waktu melakukan digit selection (pemilihan angka) pilih angka yang agak di tengah karena angka-angka ini melibatkan banyak angka pengali.
Hashing : Folding Tujuan dari folding adalah mengecilkan angka. Misalkan key terdiri dari 5 angka yang bernilai 0 – 99999. Cara folding dengan cara menjumlahkan kelima digit angka tersebut. Hasilnya adalah nilai hash mulai dari 0 sampai 45 (yaitu 9x5). Key = d1d2d3d4d5 Hash(key) = d1 + d2+ d3+ d4+ d5 Untuk mendapatkan angka yang nilai hash lebih besar, dapat digunakan “dua angka”-”dua angka” sebagai elemen. Hash(key) = 0d1 + d2d3+ d4d5 Folding jarang dipakai sendiri, tapi biasanya digabung dengan method yang lain.
Hashing : Character-valued key Digunakan untuk kunci yang tidak berupa angka melainkan berupa huruf atau karakter. Hashingnya dengan menggunakan nilai ASCII karakter tersebut. Hash(key) = ascii_value(key) mod m Misalkan sebuah key yang terdiri atas tiga huruf gunakan pendekatan seperti bilangan.Bila kunci berupa karakter ASCII standar maka diperlakukan sebagai bilangan berbasis 128. Contoh : hash(‘umn’) = (ascii_val(‘u’) x 1282 + ascii_val(‘m’) x 128 + ascii_val(‘n’) )
Hashing : Collision Keadaan dimana beberapa nilai kunci (key) di hash ke lokasi yang sama disebut collision (tabrakan). Contoh : Hash function = key mod 23 Record data dengan key= 26 akan menempati posisi = 3 Record data dengan key= 49 akan menempati posisi = 3, padahal sudah ditempati oleh record dengan key 26. Terdapat 2 kelompok metode dalam menanggani collission. Open addressing: Linier Rehashing. quadratic rehashing. double rehashing. Separate Chaining.
Hashing : Collision – Linier Rehashing. Linier Rehashing : Metode pemecahan collision dimana jika terjadi collission, akan dicari lokasi kosong berikutnya (secara linier) yang belum digunakan. Misalkan record tambahan “26, budiman, distributed computing” akan dihash ke posisi 26 % 23 = 3, dimana dilokasi tersebut sudah di tempati oleh “49, anastasya. Design of programming language”. Misalkan record tambahan “54, anjas, computational complexity” di hash ke posisi 54 % 23 = 8, yang juga telah diisi data.
Hashing : Collision – Linier Rehashing.
References : Thompson SN, 2009, Algoritma dan Struktur Data dengan C. Deitel, PJ, HM.Deitel, 2007, C How to Program, 5th Edition.