yang lebih cepat tetapi menggunakan lebih banyak memori(storage space) atau waktu yang lebih
lama tetapi menggukanan sedikit memori(storage space).
Efisiensi waktu dan efisiensi memori adalah dua hal yang berlawanan. Semakin sedikit waktu yang
dibutuhkan maka akan semakin banyak memori yang dibutuhkan, begitu pula sebaliknya semakin
banyak waktu yang dibutuhkan maka semakin banyak pula memori yang dibutuhkan.
Sorting by Counting
Counting Sort adalah algoritma pengurutan efektif dan efisien yang melakukan pengurutan dengan ide dasar
meletakkan elemen pada posisi yang benar, dimana penghitungan posisi yang benar dilakukan dengan cara
menghitung (counting) elemen-elemen dengan nilai lebih kecil atau sama dengan elemen tersebut. Contoh
sederhana saja jika terdapat 12 elemen yang lebih kecil daripada x, maka x akan mendapatkan posisinya di
posisi 13.
Source code
#include <stdio.h>
#include <string.h>
//Fungsi main yang diurutkan diberikan string arr[] dengan urutan alphabet
char output[strlen(arr)];
memset(count, 0, sizeof(count));
++count[arr[i]];
count[i] += count[i-1];
output[count[arr[i]]-1] = arr[i];
--count[arr[i]];
arr[i] = output[i];
int main()
countSort(arr);
return 0;
}
Flowchart Start
Input kata
geeksforgeeks
Output kata
menjadi
eeeefggkkors
END
Input Enhancement in String Matching: Horspool’s
and Boyer-Moore Algorithm
Pada bagian ini, kita melihat bagaimana teknik input enhancement dapat diterapkan pada
masalah matching string. Ingat bahwa masalah pencocokan string memerlukan pencarian
terjadinya string karakter m yang disebut pola dalam string karakter n yang lebih panjang
yang disebut teks.
Karena jumlah maksimum uji coba tersebut adalah n - m + 1 dan, dalam kasus terburuk,
perbandingan yang perlu dilakukan pada masing - masing, efisiensi kasus terburuk dari
algoritma brute force adalah kelas O (nm) . Rata-rata, bagaimanapun, kita harus
mengharapkan hanya beberapa perbandingan sebelum pergeseran pola, dan untuk teks
bahasa alami acak, efisiensi kasus rata-rata memang ternyata berada di O (n + m).
Beberapa algoritma yang lebih cepat telah ditemukan. Kebanyakan dari mereka
memanfaatkan gagasan peningkatan input: preprocess pola untuk mendapatkan beberapa
informasi tentang hal itu, menyimpan informasi ini dalam sebuah tabel, dan kemudian
menggunakan informasi ini selama pencarian pola yang sebenarnya dalam teks tertentu.
Inilah ide di balik dua algoritma yang paling dikenal dari tipe ini: algoritma Knuth-Morris-Pratt
[Knu77] dan algoritma Boyer-Moore [Boy77].
Perbedaan utama antara kedua algoritma ini terletak pada cara mereka membandingkan
karakter dari sebuah pola dengan rekan mereka dalam sebuah teks: algoritma Knuth-Morris-
Pratt melakukannya dari kiri ke kanan, sedangkan algoritma Boyer-Moore melakukannya
dari kanan ke kiri. Karena gagasan terakhir mengarah ke algoritma yang lebih sederhana,
inilah satu-satunya yang akan kita kejar di sini. (Perhatikan bahwa algoritma Boyer-Moore
dimulai dengan menyelaraskan pola terhadap karakter awal teks; jika percobaan pertama
gagal, itu menggeser pola ke kanan. Ini adalah perbandingan dalam percobaan yang
dilakukan algoritma kanan ke kiri, mulai dengan karakter terakhir dalam pola.)
Jika terjadi ketidakcocokan, kita perlu menggeser pola ke kanan. Jelas, kami ingin
melakukan perubahan besar mungkin tanpa mempertaruhkan kemungkinan kehilangan
substring yang sesuai dalam teks. Algoritma Horspool menentukan ukuran pergeseran
seperti itu dengan melihat karakter c dari teks yang sesuai dengan karakter terakhir dari
pola. Ini adalah kasus bahkan jika karakter c sendiri sesuai dengan mitranya dalam pola.
Boyer-Moore Algorithm
Sekarang kita garis bawahi algoritma Boyer-Moore itu sendiri. Jika perbandingan pertama
dari karakter paling kanan dalam pola dengan karakter c yang sesuai di dalam teks gagal,
algoritma melakukan hal yang persis sama dengan algoritma Horspool. Yakni, menggeser
pola ke kanan dengan jumlah karakter yang diambil dari tabel precomputed seperti yang
dijelaskan sebelumnya.
Kedua algoritma tersebut bertindak secara berbeda, namun setelah beberapa bilangan
positif k (0 <k <m) dari karakter pola dicocokkan dengan sukses sebelum terjadi
ketidaksesuaian:
Dalam situasi ini, algoritma Boyer-Moore menentukan ukuran pergeseran dengan
mempertimbangkan dua kuantitas. Yang pertama dipandu oleh karakter teks c yang
menyebabkan ketidakcocokan dengan mitranya dalam pola. Dengan demikian, ini disebut
pergeseran simbol buruk. Alasan di balik pergeseran ini adalah alasan yang kami gunakan
dalam algoritma Horspool. Jika c tidak sesuai dengan pola, kita ubah pola untuk hanya
melewatkan huruf c ini di teks. Dengan mudah, ukuran pergeseran ini dapat dihitung dengan
rumus t1 (c) - k dimana t1 (c) adalah entri pada tabel precomputed yang digunakan oleh
algoritma Horspool (lihat di atas) dan k adalah jumlah karakter yang cocok:
B Tree
B – tree adalah sebuah tree yang dapat menyimpan data secara berurutan dan
memungkinkan untuk pencarian, akses sekuensial, penambahan, serta penghapusan dalam
waktu yang relatif singkat. B – tree adalah generalisasi dari binary search tree, di mana
setiap node dapat memiliki lebih dari 2 chlidren. Tidak seperti self – balancing binary search
trees, B – tree lebih dikhususkan untuk sistem yang membutuhkan pembacaan dan
penulisan data dalam jumlah yang relatif besar / banyak. B – tree biasadigunakan untuk
database dan filesystem.
Dalam B – tree, internal nodes (non - leaf) dapat memiliki variabel jumlah node
anak dalam batas yang sudah ditentukan. Ketika sebuah data ditambahkan atau dihapus
dari sebuah node, jumlah node anak dari tree tersebut berubah. Dengan tujuan untuk
mempertahankan batas yang sudah ditentukan tersebut, internal nodes dapat bergabung
atau berpisah. Karena berbagai batas dari node – node anak diijinkan, maka B – tree tidak
perlu menyeimbangkan diri sesering mungkin layaknya self – balancing search trees,tetapi
hal semacam ini akan membuang – buang tempat yang ada, karena setiap node yang ada
tidak terisi semua. Batas bawah dan batas atas pada jumlah node anak biasanya tetap
untuk implementasi tertentu. Sebagai contoh, pada 2 – 3 tree, setiap internal node hanya
dapat memiliki 2 atau 3 node – node anak.
Jumlah cabang (anak node) dari sebuah node akan satu lebih banyak dari jumlah
kunci yang tersimpan dalam node. Dalam sebuah 2-3 B – tree, node internal akan
menyimpan baik satu kunci (dengan 2 buah node anak) atau dua kunci (dengan tiga node
anak). Sebuah B- tree kadang – kadang digambarkan dengan parameter (d + 1) – (2d +
1) atau yang lebih mudah dengan urutan cabang tertinggi, (2d + 1).
Sebuah B – tree akan tetap seimbang dengan syarat semua node – node daun
(node terluar) berada dalam kedalaman yang sama. Kedalaman ini akan bertambah secara
perlahan – lahan sebagai satu syarat yang ditambahkan pada sebuah tree, tetapi
pertambahan pada keseluruhan kedalaman jarang terjadi, dan sebagai hasilnya pada
semua node - node daun menjadi satu node lebih jauh dari root – nya.
Searching
Searching dalam B – tree mirip dengan searching dalam binary search tree. Dimulai
dari root, tree akan dilaluli secara rekursif dari atas sampai bawah (root sampai node
terluar). Dalam setiap level, search memilih sebuah child pointer (subtree) yang
memisahkan nilai – nilai pada kedua sisi dari nilai pencarian.
Binary search biasanya (tapi tidak selalu) digunakan dalam setiap node untuk
menemukan nilai – nilai pemisahan dan nilai penting dari child tree.
Insertion
Setiap penambahan dimulai dari sebuah node daun (node terluar). Untuk
menambahkan sebuah elemen (data) baru.
Pencarian dilakukan pada tree untuk menemukan node terluar di mana elemen
baru (data) harus ditambahkan. Tambahkan data baru tersebut ke dalam node dengan
langkah – langkah berikut :
1. Jika node berisi lebih sedikit dari jumlah elemen (data) maksimum yang
sudah ditentukan, maka terdapat ruangan untuk elemen yang baru (data
baru). Tambahkan elemen baru tersebut ke dalam node, jaga data – data
dalam node tetap teratur.
2. Jika node – node sudah penuh, sehingga terbagi rata menjadi 2 node,
Sebuah median tunggal dipilih dari antara unsur – unsur daun dan
elemen baru.
Nilai yang kurang dari median diletakkan pada node baru sebelah
kiri dan nilai yang lebih dari median diletakkan pada node baru
sebelah kanan, dengan median bertindak sebagai nilai pemisah.
Tambahkan nilai pemisah pada node parent, yang akan
menyebabkan node tersebut akan memisah, dan seterusnya. Jika
node tidak memiliki parent (yaitu jika node adalah root), buat root
baru di atas node tersebut (menambahkan tinggi dari tree tersebut).
Deletion
Temukan dan hapus data itu, kemudian atur ulang tree untuk mengembalikan
keseimbangannya
atau
Lakukan single pass pada tree tersebut, tetapi sebelum masuk pada sebuah node,
atur ulang tree sehingga setelah data yang akan dihapus ditemukan. Data tersebut
dapat dihapus tanpa memicu terjadinya atur ulang kembali.