Modul Algoritma & Pemrograman Bahasa C - Pencarian Dan Pengurutan
Modul Algoritma & Pemrograman Bahasa C - Pencarian Dan Pengurutan
4.1 Tujuan
Tujuan modul IV ini, adalah:
• Praktikan bisa membuat beberapa program pencarian berdasarkan metode
algoritma pencarian
• Praktikan bisa membuat beberapa program pengurutan berdasarkan metode
algoritma pengurutan
• Praktikan dapat membiasakan diri untuk membuat program secara terstruktur.
• Praktikan memahami algoritma beberapa metode pencarian dan pengurutan
4.2 Teori
4.2.1 Pencarian
Proses pencarian (searching) adalah menemukan nilai (data) tertentu di
dalam sekumpulan data yang bertipe sama (baik bertipe dasar atau bertipe
bentukan).
IV-1
IV-2
Deklarasi
K : integer {indeks larik}
Deskripsi
K←1
While (K < N) and L[K] ≠ X) do
K←K+1
Endwhile
{K = N or L[K] = X}
If L[K] = X then {X ditemukan}
Ketemu ← true
Else
Ketemu ← false
Endif
Algoritma Pencarian
{program untuk mencari nilai tertentu dengan sequential search}
Deklarasi
Const NMaks = 100 {jumlah maksimum elemen larik}
Type Larikint : array[1..NMaks] of integer
L : Larikint
X : integer {elemen yang dicari}
Found : Boolean {true jika X ditemukan, false jika X tidak}
masukan}
Deskripsi
Read(N)
Bacalarik(L,N)
Read(X)
SeqSearch(L, N, X, Found)
If Found then
Write(X, ‘ditemukan’)
Else
Write(X, ‘tidak ditemukan’)
Endif
Deklarasi
K : integer {indeks larik}
Deskripsi
K←1
While (K<N) and (L[K] ≠ X) do
K←K+1
Endwhile
{K = N or L[K] = X}
Deklarasi
X : integer {indeks untuk pencarian}
Deskripsi
K←1
Ketemu ← false
While (K ≤ N) and (not Ketemu) do
If L[K] = X then
Ketemu ← true
Else
K ← K+1
Endif
Endwhile
{K > N or Ketemu}
return ketemu
Deklarasi
K : integer {indeks untuk pencarian}
Ketemu : Boolean {true bila X ditemukan, false bila tidak}
Deskripsi
K←1
Ketemu ← false
While (K ≤ N) and (not ketemu) do
If L[K] = X then
IV-5
Ketemu ← true
Else
K←K+1
Endif
Endwhile
{K > N or Ketemu}
{simpulkan hasil pencarian}
if (L[K] = X) then {X ditemukan}
return K {indeks elemen L yang berisi X}
else
return -1 {X tidak ditemukan, indeks = -1}
endif
Contoh Algoritma 5:
Procedure SeqSearch(input L : Larikint, input N : integer, input X : integer,
output IDX : integer)
{mencari keberadaan nilai X di dalam larik[1..N] yang elemen-elemen sudah
terurut menaik}
{k.awal : nilai X dan elemen larik L[1..N] sudah terdefinisi elemen-elemen
larik L sudah terurut menaik}
{k.akhir : IDX berisi indeks larik L yang berisi nilai X. jika X tidak ditemukan,
maka IDX diisi dengan nilai -1}
Deklarasi
K : integer {indeks larik}
Deskripsi
K←1
While (K < N) and (L[K] < X) do
K←1
Endwhile
(K = N or L[K] ≥ X)
If L[K] = X then {X ditemukan}
IDX ← K
Else
IDX ← -1
Endif
Penelitian para ahli menunjukkan bahwa metode ini berjalan dengan sangat efektif
dan efisien dibandingkan pencarian berurutan yang tidak terurut, jikaq data yang
dicari berada (relatif) pada bagian awal larik. Tetapi, karena kondisi berhenti yang
kita tentukan, metode ini kurang lebih berkinerja sama dengan pencarian
berurutan jika data yang dicari terletak di bagian akhir larik.
0 5 6 10 11 12 32 34 56 99
Misalkan, kita ingin mencari posisi dari nilai 56. Pertama kali, larik di atas dapat
kita bagi menjadi 2 sublarik sebagai berikut:
0 5 6 10 11 12 32 34 56 99
Sublarik 1 Sublarik 2
Kemudian, data (56) dibandingkan dengan elemen terakhir pada sublarik 1 (yang
bernilai 11). Jika data tersebut (56) lebih kecil dari elemen terakhir pada sublarik1
(11) maka data akan dicari di subvektor 1. Jika tidak, berarti data akan dicari di
sublarik 2 dan sublarik 1 tidak perlu dihiraukan lagi. Proses di atas diulangi lagi.
Sublarik 2 dibagi 2 lagi sehingga menghasilkan sublarik dibawah ini:
12 32 34 56 99
Sublarik 2.1 Sublarik 2.2
Kita bandingkan lagi data (56) dengan elemen terakhir sublarik 2.1 (34). Ternyata
data (56) lebih besar dari (34), maka pasti data yang dicari ada di sublarik 2.2.
terakhir, sublarik 2.2 dipecah lagi. Hasilnya adalah sebagai berikut:
56 99
Sublarik 2.2.1 Sublarik 2.2.2
Demikian dengan 4 iterasi kita sudah menemukan data yang kita cari.
Contoh Algoritma 6:
Procedure BinarySearch(input L : Larikint, input N : integer, input X : integer,
output Idx : integer)
{mencari X di dalam larik L[1..N] yang sudah terurut menaik dengan metode
pencarian bagidua, keluaran prosedur ini adalah indeks elemen larik yang
berisi X. idx diisi 0 jika X tidak ditemukan.}
{k.awal: larik L[1..N] sudah berisi data yang sudah terurut menaik, dan X
adalah nilai yang akan dicari}
{k.akhir: idx berisi indeks larik tempat X ditemukan, idx=0 jika X tidak
ditemukan}
Deklarasi
I, J : integer {indeks kiri dan indeks kanan}
K : integer {indeks elemen tengah}
Ketemu : Boolean {flag untuk menentukan apakah X ditemukan}
Deskripsi
I←1
J←N
Ketemu ← false
IV-8
4.2.2 Pengurutan
Pengurutan (sorting) adalah proses mengatur sekumpulan objek menurut
urutan atau susunan tertentu. Urutan objek tersebut dapat menaik (ascending) atau
menurun (descending). Bila N buah objek atau data disimpan di dalam larik L,
maka pengurutan menaik berarti menyusun elemen larik sedemikian sehingga:
L[1] ≤ L[2] ≤ L[3 ≤ … ≤ L[N]
Sedangkan pengurutan menurun berarti menyusun elemen larik sedemikian
sehingga:
L[1] ≥ L[2] ≥ L[3 ≥ … ≥ L[N]
Data yang diurut dapat berupa data bertipe dasar atau tipe terstruktur (record).
Jika data bertipe terstruktur, maka harus dispesifikasikan berdasarkan field apa
data tersebut diurutkan. Field yang dijadikan dasar pengurutan dikenal sebagai
field kunci.
Adanya kebutuhan terhadap proses pengurutan memunculkan bermacam-
macam metode pengurutan. Metode tersebut diantaranya adalah: 1) Metode
Pengurutan Gelembung (Bubble Sort), 2) Metode Pengurutan Pilih (Selection
Sort), 3) Metode Pengurutan Sisip (Insertion Sort), 4) Metode Pengurutan Shell
(Shell Sort), 5) Heap Sort, 6) Quick Sort, 7) Merge Sort, 8) Radix Sort dan 9)
Tree Sort. Pada modul ini, tidak semua metode pengurutan akan dibahas.
Tidak ada metode yang terbaik untuk pengurutan. Kebanyakan metode
pengurutan sederhana hanya bagus untuk volume data yang kecil tetapi lambat
untuk ukuran data yang besar. Metode pengurutan yang lebih cepat pun (seperti
IV-9
quick sort dan merge sort) memang bagus untuk mengurutkan data yang banyak,
tetapi tidak bagus untuk ukuran data yang sedikit karena memerlukan beban
tambahan (overhead) yang boros waktu dan memori.
Metode pengurutan dapat diklasifikasikan sebagai berikut:
a. Metode pengurutan internal, yaitu metode pengurutan untuk data yang
disimpan di dalam memori computer. Umumnya struktur internal yang
dipakai untuk pengurutan internal adalah larik, sehingga pengurutan
internal disebut juga pengurutan larik.
b. Metode pengurutan eksternal, yaitu metode pengurutan untuk data
yang disimpan di dalam disk storage, disebut juga pengurutan arsip
(file), karena struktur eksternal yang dipakai adalah arsip.
Contoh Algoritma 1:
Procedure BubbleSort(input/output L : Larikint, input N : integer)
{mengurutkan larik L[1..N] sehingga terurut menaik dengan metode
pengurutan gelembung}
{k.awal : elemen larik L sudah terdefinisi nilai-nilainya}
{k.akhir : elemen larik L terurut menaik sedemikian sehingga L[1] ≤ L[2] ≤ .. ≤
L[N]}
Deklarasi
I : integer {pencacah untuk jumlah langkah}
K : integer {pencacah untuk pengapungan pada setiap langkah}
Deskripsi
For I ← 1 to N – 1 do
For K ← N downto I + 1 do
If L[K] < L[K-1] then
{pertukarkan L[K] dengan L[K-1]}
tukar(L[K], L[K-1])
endif
endfor
endfor
Bagaimana dengan algoritma pilih maksimum terurut menurun?
Pengurutan gelembung merupakan metode pengurutan yang tidak efisien. Hal ini
disebabkan oleh banyaknya operasi pertukaran yang dilakukan pada setiap
langkah pengapungan. Untuk nukuran larik yang besar, pengurutan dengan
metode ini membutuhkan waktu yang lama. Karena alasan itu, maka metode ini
jarang digunakan dalam praktek. Namun, kelebihan metode ini adalah pada
kesederhanaannya dan mudah dipahami.
Contoh Algoritma 2:
Procedure SelectionSort(input/output L : Larikint, input N : integer)
{mengurutkan elemen larik L[1..N] sehingga tersusun menaik dengan
metode pengurutan maksimum}
{k.awal : elemen larik L sudah terdefinisi harganya}
{k.akhir : elemen larik L terurut menaik sedemikian sehingga L[1] ≤ L[2] ≤
... ≤ L[N]}
Deklarasi
I : integer
J : integer {pencacah untuk mencari nilai maksimum}
Imaks : integer {indeks yang berisi nilai maksimum sementara}
Deskripsi
For I ← N downto 2 do {jumlah pengulangan sebanyak N-1}
{cari elemen maksimum pada elemen L[1..I]}
Imaks ← I {elemen pertama diasumsikan sebagai
elemen maksimum sementara}
For J ← 2 to I do
If L[J] > L[Imaks] then
Imaks ← J
IV-12
Endif
Endfor
{pertukarkan L[Imaks] dengan L[I]}
Tukar(L[Imaks], L[I])
Endfor
Bagaimana dengan algoritma pilih maksimum terurut menurun?
Contoh Algoritma 3:
Procedure SelectionSort(input/output L : larikint, input N : integer)
{mengurutkan elemen larik L[1..N] sehingga tersusun menaik dengan
metode pengurutan pilih minimum}
{k.awal : elemen larik L sudah terdefinisi harganya}
{k.akhir : elemen larik L terurut menaik sedemikian sehingga L[1] ≤ L[2] ≤
... ≤ L[N]}
Deklarasi
I : integer
J : integer {pencacah untuk mencari nilai maksimum}
Imin : integer {indeks yang berisi nilai maksimum sementara}
Deskripsi
For I ← 1 to N-1 do
IV-13
Contoh Algoritma 4:
Procedure InsertionSort(input/output L : Larikint, input N : integer)
{mengurutkan elemen larik L[1..N] sehingga tersusun menaik dengan metode
pengurutan sisip}
{k.awal : elemen-elemen larik L sudah terdefinisi nilainya}
{k.akhir : elemen larik L terurut menaik sedemikian sehingga L[1] ≤ L[2] ≤ ...
≤ L[N]}
IV-14
Deklarasi
I : integer
J : integer {pencacah untuk mencari nilai maksimum}
Y : integer {peubah boolean untuk menyatakan posisi penyisipan
ditemukan}
Ketemu : boolean
Deskripsi
{elemen L[1] dianggap sudah terurut}
For I ← 2 to N do {mulai dari langkah 2 sampai langkah N}
{sisipkan L[I] ke dalam bagian yang sudah terurut}
Y ← L[I]
{cari posisi yang tepat untuk Y di dalam L[1..I-1] sambil menggeser}
J←I–1
Ketemu ← false
While (J≥1) and (not Ketemu) do
If Y < L[J] then
L[J+1] ← L[J]
J←J–1
Else
Ketemu ← true
Endif
Endwhile
{J < 1 or Ketemu}
L[J+1] ← Y {sisipkan Y pada tempat yang sesuai}
Endfor
Bagaimana algoritma pengurutan sisip untuk pengurutan menurun??
bernilai setengah jarak yang semula. Kemudian, pembandingan dan penukaran itu
dilanjutkan dengan jarak yang baru. Demikian selanjutnya hingga jarak sama
dengan 1.
Untuk memperjelas metode pengurutan shell adalah sebagai berikut:
Data sebelum diurutkan:
23 45 12 24 56 34 27 23 16
1 2 3 4 5 6 7 8 9
Semula 23 45 12 24 56 34 27 23 16
Jarak = 4 23 45 12 24 56 34 27 23 16
23 45 12 24 56 34 27 23 16
23 34 12 24 56 45 27 23 16
23 34 12 24 56 34 27 23 16
23 34 12 23 56 34 27 24 16
23 34 12 23 16 45 27 24 56
Jarak=2 23 34 12 23 16 45 27 24 56
12 34 23 23 16 45 27 24 56
12 23 23 34 16 45 27 24 56
12 23 16 34 23 45 27 24 56
12 23 16 34 23 45 27 24 56
12 23 16 34 23 45 27 24 56
12 23 16 34 23 24 27 45 56
12 23 16 34 23 24 27 45 56
Jarak=1 12 23 16 34 23 24 27 45 56
12 23 16 34 23 24 27 45 56
12 16 23 34 23 24 27 45 56
12 16 23 34 23 24 27 45 56
12 16 23 23 34 24 27 45 56
12 16 23 23 34 34 27 45 56
12 16 23 23 23 27 34 45 56
12 16 23 23 23 27 34 45 56
12 16 23 23 23 27 34 45 56
Contoh Algoritma 5
Procedure ShellSort(input/output A : Larikint, input N : integer)
{mengurutkan elemen larik L[1..N] sehingga tersusun menaik dengan metode
pengurutan shell}
{k.awal: elemen-elemen larik L sudah terdefinisi nilainya}
{k.akhir: elemen-elemen larik L terurut menaik}
IV-16
Deklarasi
I : integer
J : integer
Jarak : integer
Deskripsi
Jarak ← N div 2
While jarak > 0 do
For I ← 1 to N – Jarak do
J ← I+Jarak
If A[I] > A[J] then
Tukar(A[I], A[J])
Endif
Jarak ← Jarak div 2
Endfor
Endwhile
Semula 5 10 0 12 32 56 6 34 11 99
Semula 0 5 10 12 6 32 34 56 11 99
Semula 0 5 6 10 12 32 34 56 11 99
Semula 0 5 6 10 11 12 32 34 56 99
IV-17
Contoh Algoritma 6:
Procedure Merge(input/output A, B : Larik, Output Awal,Tengah,Akhir :
integer)
Deklarasi
I, J, K, T : integer
Deskripsi
I ← Awal
K ← Awal
J ← Tengah + 1
Do
If A[I] < A[J] then {elemen sebelah kiri lebih kecil}
B[K] ← A[I]
I←I+1
Else
B[K] ← A[J] {elemen sebelah kanan lebih besar}
J←J+1
Endif
K←K+1
While ((I ≤ Tengah) or (J ≤ Akhir))
{memasukkan sisa elemen saat 2 larik tidak sama panjang}
if I > Tengah then {larik kiri lebih dulu habis}
for T ← J to Akhir
B[K+T-J] ← A[T]
Endfor
Else {elemen kanan habis lebih dulu}
For T ← I to Tengah
B[K+T-I] ← A[T]
Endfor
Endif
Procedure Iterasi(input/output A, B : Larik, Input N, Cacah : integer)
Deklarasi
I, T : integer
Deskripsi
I←1
While I < (N – 2*Cacah + 1) do
Merge(A, B, I, I+Cacah-1, N)
I ← I + 2*Cacah
Endwhile
If (I+Cacah-1) < N then {penggabungan ke sublarik}
Merge(A, B, I, I+Cacah-1, N)
Else
For T ← I to N do
B[T] ← A[T]
IV-18
Endfor
Endif
Algoritma Mergesort
{mengurutkan elemen larik sehingga tersusun menaik dengan metode
pengurutan merge}
{k.awal: elemen-elemen larik yang sudah terdefinisi nilainya}
{k.akhir: elemen-elemen larik terurut menaik}
Deklarasi
Cacah : integer
B : Larik
Deskripsi
Cacah ← 1
While Cacah < N do
Iterasi(A, B, N, Cacah)
Cacah ← Cacah * 2
Iterasi(B, A, N, Cacah)
Cacah ← Cacah * 2
Endwhile
4.3 Kasus
4.3.1 Kasus 1
Buatlah algoritma larik terstruktur data mahasiswa yang terdiri dari Nim,
Nama mahasiswa, Jenis Kelamin dan Kelas. Kemudian buatlah algoritma
pencarian larik terstruktur tersebut dengan menggunakan 2 metode pencarian
diatas. Buatlah programnya dan bandingkan iterasi dari kedua program tersebut!
4.3.2 Kasus 2
Buatlah algoritma dan program untuk mengurutkan data dengan
menggunakan salah satu metode pengurutan. Ada empat data yang harus
diurutkan:
• Nomor Induk, bertipe bilangan bulat
• Nama, bertipe string
• Alamat, bertipe string
• Golongan, bertipe char (dapat bernilai ’A’, ’B’...)
Prosedur pengurutan menerima satu parameter yaitu bilangan bulat yang dapat
bernilai 1,2 dan 3. Apabila bernilai 1, maka data diurutkan berdasarkan nomor
IV-19
induk. Apabila bernilai 2, maka data diurutkan berdasarkan nama. Yang terakhir,
apabila bernilai 3, maka data diurutkan menurut golongan.