Anda di halaman 1dari 11

ANALISIS ALGORITMA PADA MASALAH SORTING

Dalam ilmu komputer, algoritma pengurutan adalah

• algoritma yang meletakkan elemen-elemen suatu kumpulan data dalam


urutan tertentu. Atau

• proses pengurutan data yg sebelumnya disusun secara acak sehingga


menjadi tersusun secara teratur menurut suatu aturan Tertentu.

• Yang pada kenyataannya ‘urutan tertentu’ yang umum digunakan adalah


secara terurut secara numerikal ataupun secara leksikografi (urutan secara
abjad sesuai kamus).

• Ada 2 jenis sorting : Ascending (naik) & Descending (turun)

Jenis-jenis algoritma pengurutan :

• Exchange Sort

melakukan pembandingan antar data, dan melakukan pertukaran apabila


urutan yang
didapat belum sesuai.

Contohnya : Bubble sort, Cocktail sort, Comb sort, Gnome sort, Quicksort.

• Selection Sort

mencari elemen yang tepat untuk diletakkan di posisi yang telah diketahui,
dan meletakkannya di posisi tersebut setelah data tersebut ditemukan.

Contohnya :Selection sort, Heapsort, Smoothsort, Strand sort

• Insertion Sort

mencari tempat yang tepat untuk suatu elemen data yang telah diketahui ke
dalam subkumpulan data yang telah terurut, kemudian melakukan
penyisipan (insertion) data di tempat yang tepat tersebut.

Contohnya adalah : Insertion sor, Shell sort, Tree sort, Library sort, Patience
sorting.
• Merge Sort

data dibagi menjadi subkumpulan-subkumpulan yang kemudian


subkumpulan tersebut diurutkan secara terpisah, dan kemudian
digabungkan kembali dengan metode merging. algoritma ini melakukan
metode pengurutan merge sort juga untuk mengurutkan subkumpulandata
tersebut, atau dengan kata lain, pengurutan dilakukan secara rekursif.

Contohnya adalah : Merge sort.

• Non-Comparison Sort

proses pengurutan data yang dilakukan algoritma ini tidak terdapat


pembandingan
antardata, data diurutkan sesuai dengan pigeon hole principle.
Contohnya adalah : Radix sort, Bucket sort, Counting sort, Pigeonhole sort,
Tally sort.

Kompleksitas Algoritma
Kompleksitas dari suatu algoritma merupakan ukuran seberapa banyak
komputasi yang dibutuhkan algoritma tersebut untuk mendapatkan hasil
yang diinginkan. Algoritma yang dapat memperoleh hasil yang diinginkan
dalam waktu yang singkat memiliki kompleksitas yang rendah, sementara
algoritma yang membutuhkan waktu yang lama untuk memperoleh hasil
tersebut mempunyai kompleksitas yang tinggi. Biasanya kompleksitas
algoritma dinyatakan secara asimptotik dengan notasi big-O.
Jika kompleksitas waktu untuk menjalankan suatu algoritma dinyatakan
dengan T(n), dan memenuhi T(n) ≤ C(f(n)) untuk n ≥ n0 maka kompleksitas
dapat dinyatakan dengan
T(n) = O(f(n)).

1. Radix sort

Ide dasar dari metode Radix sort ini adalah mengkategorikan data-data
menjadi sub kumpulan subkumpulan data sesuai dengan nilai radix-nya
mengkonkatenasinya, kemudian
mengkategorikannya kembali berdasar nilai radix lainnya.

Contohnya adalah pengurutan sebuah kumpulan data bilangan bulat dengan


jumlah digit maksimal 3
121 076 823 367 232 434 742 936 274

Pertama – tama dibagi sesuai digit yang paling kanan

121 076 823 367 232 434 742 936 274

Kateg Isi
ori
digit
0 -
1 121
2 232,742
3 823
4 434,274
5 -
6 76,936
7 367
8 -
9 -

Lalu diurutkan menjadi

121 232 742 823 434 274 076 936 367

Lalu diurutkan lagi sesuai digit kedua

Kategori Isi
digit
0
1
2 121,823
3 232,434,936
4 742
5
6 367
7 274,076
8
9

Lalu diurutkan menjadi :

121,823,232,434,936,742,367,274,076,
Kemudian diurutkan lagi sesuai digit ketiga :

Kategor Isi
i digit
0 076
1 121,
2 232,274
3 367
4 434
5
6
7 742
8 823
9 936

Maka hasil pengurutannya :

076 121 232 274 367 434 742 823 936

Implementasi dalam bilangan


pecahan negatif [7]
Terdapat kekacauan bila dengan penyelesaian pengurutan bilangan pecahan
positif diimplementasikan pada kasus ini, karena bilangan pecahan negatif
diurutkan pada posisi terakhir, misalnya seperti :
2083.000000
2785.000000
8080.000000
10116.000000
10578.000000
12974.000000
-660.000000
-4906.000000
-10050.000000
-16343.000000
Dapat dilihat bahwa nilai negatifnya sudah terurut namun dalam tempat dan
susunan yang salah (urutan dimulai dari yang terbesar). Solusinya yang
pertama yaitu perlu mencari banyak nilai negatif. Tanda suatu bilangan
ditentukan oleh MSB dan yang ingin kita cari adalah nomor entitas yang
memiliki MSB 1.Pada proses radix, terdapat 128 entri pada counter terakhir.
Yang harus dilakukan adalah menjumlahkannya :

NbNegativeValues = 0;
For (i=128; i<256, i++) {
NbNegatifValues+=
LastCounter[i];
}
Untuk pengurutan yang kurang dari 128 entri, algoritma brute force akan
bekerja lebih efisien.
Namun, radix sort merupakan algoritma yang bertujuan mengurutkan
sejumlah informasi yang
berjumlah relatif besar. Yang perlu dilakukan untuk menutupi kelemahan
algoritma ini agar mendapatkan hasil pengurutan akhir yang benar adalah
memperbaiki dua hal, yaitu tempat dan
susunan yang belum benar

Pertama, perbaikan jika entri bilangan positif. Misalkan M adalah sebuah


bilangan entri negative yang telah dihitung sebelumnya, harus dipastikan
bahwa pecahan positif dimulaisetelah pecahan yang negatif. Perbaikan pada
tempat yang salah dilakukan dengan memaksa offset positif yang pertama
sebagai M.

Offset[0] = M;

Karena pengurutan untuk entri bilangan positif sudah benar, maka perbaikan
untuk kasus bilangan positif sudah selesai. Selanjutnya, perbaikan jika entri
adalah bilangan negatif. Ambil kembali -16343.0 yang merupakan hasil
pengurutan terakhir dari pengurutan di atas. Seharusnya entri ini berada
pada urutan paling awal setelah proses pengurutan dilakukan. Perbaikan
pertama dengan memaksa membersihkan offset yang relatif terhadap entri
paling akhir.

Offset[255] = 0;

Dari sini akan diurutkan sisa entri negatif dalam susunan menaik, dengan
cara membalik susunan pada status awal radix sort.

for(i=0;i<127;i++){
Offset[254-i] =
Offset[255-i] +
LastCounter[255-i];
}

Kode ini mengurutkan offset pada range 254-0 s.d. 255-126 yaitu dari 254
s.d. 128, atau dengan kata lain offset dalam entri negatif. Mengurutkannya
dalam susunan terbalik, memulai dari offset 255 (null), akan membuat
pecahan negatif dalam susunan benar.

Algoritma dan Kompleksitas Waktu Radix Sort [3]

Asumsikan bahwa kunci item yang diurutkan mempunyai rentang k, fi| i=0..k-1, dan
setiap fi
memiliki nilai diskret si, lalu prosedur radix sortnya dapat dituliskan seperti berikut :

radixsort( A, n ) {
for(i=0;i<k;i++) {
for(j=0;j<si;j++)
bin[j] = EMPTY; O(si)

for(j=0;j<n;j++) {
move Ai to the end of bin[Ai->fi] O(n
} )

for(j=0;j<si;j++)
concatenate bin[j] onto the end
of A;
}} O(si)

Radix Sort merupakan teknik algoritma pengurutan


Sekarang misalnya kita ambil contoh kuncinya yaitu bilangan integer dalam
range (0,bk-1), untuk beberapa nilai konstan k, lalu kunci tersebut dapat
dilihat sebagai k-digit base-b integers. Jadi, si = b untuk semua i dan
kompleksitas waktunya menjadi O(n+kb) atau O(n). Jika k diperbolehkan
ditambah dengan n, maka kita mendapatkan kasus berbeda. Contohnya
yaitu dibutuhkan log2n digit biner untuk merepresentasikan sebuah integer
< n. Jika panjang kunci diperbolehkan ditambah dengan n, maka k = log n,
dan kita mendapatkan :

Kesimpulan : yang banyak mengundang kontrovensi, sebagaimana yang


diketahui banyak orang bahwa kemampuannya terbatas pada bilangan
integer. Namun seiring dengan eksplorasi yang dilakukan, ternyata Radix
Sort juga bisa digunakan untuk mengurutkan bilangan pecahan bahkan
pecahan negatif. Metode ini men-scanning digit-digit pada suatubilangan
yang dirunut dari digit terakhir hingga digit pertama, tetapi bukanlah
masalah untuk mengatasi bilangan pecahan yaitu dengan
merepresentasikan 5 bilangan tersebut ke dalam representasi biner atau
heksa yang memiliki konfigurasi tertentu dengan kompleksitas waktu yang
sebanding dengan metode pencarian yang telah diakui oleh banyak orang
sebagai metode tercepat, yaitu Quick Sort. Atau bahkan metode Radix Sort
ini memiliki kompleksitas waktu yang lebih cepat dari Quick Sort dalam
kasus tertentu.

#include <iostream.h>
#include <stdlib.h>
#include <string.h>

void radix (int byte, long N, long *source, long *dest)


{
long count[256];
long index[256];
memset (count, 0, sizeof (count));
for ( int i=0; i<N; i++ ) count[((source[i])>>(byte*8))&0xff]++;

index[0]=0;
for ( i=1; i<256; i++ ) index[i]=index[i-1]+count[i-1];
for ( i=0; i<N; i++ ) dest[index[((source[i])>>(byte*8))&0xff]++] =
source[i];
}

void radixsort (long *source, long *temp, long N)


{
radix (0, N, source, temp);
radix (1, N, temp, source);
radix (2, N, source, temp);
radix (3, N, temp, source);
}

void make_random (long *data, long N)


{
for ( int i=0; i<N; i++ ) data[i]=rand()|(rand()<<16);
}

long data[100];
long temp[100];

void main (void)


{
make_random(data, 100);
radixsort (data, temp, 100);
for ( int i=0; i<100; i++ ) cout << data[i] << '\n';
}

2. Bubble sort

Algoritma dimulai dari elemen paling awal.


2 buah elemen pertama dari list dibandingkan. Jika elemen pertama lebih
besar dari elemen kedua kedua,dilakukan pertukaran. Langkah 2 dan 3
dilakukan lagi terhadap elemen kedua dan ketiga, seterusnya sampai ke
ujung elemen Bila sudah sampai ke ujung dilakukan lagi ke awal sampai
tidak ada terjadi lagi pertukaran elemen. Bila tidak ada pertukaran elemen
lagi, maka list elemen sudah terurut.
Pada iterasi ke-i, pemeriksaan tsb. dilakukan pula dalam loop-for sbb.

deskripsi
adatukar true
I 1
While (I<n) and (adatukar) do
J 1
Adatukar false
While j <= (n-I) do
If x[j] > x[j+1] then
Adatukar true
temp x[j]
X[j] x[j+1]
x[j+1] temp
endif
j j+1
endwhile
I i+1
endwhile
Loop-for tersebut akan menggeser bilangan bilangan terkecil ke posisi i.
Loop-for dilakukan hanya sampai ke i karena pada iterasi ke-i data dalam
x[0], x[1], ..., x[I 1] merupakan yang paling kecil dan sudah terurut hasil
pengeseran yang dilakukan setiap loop sebelumnya. Oleh sebab itu iterasi
hanya dilakukan untuk harga i=0, 1, ..., n-2 atau sampai tidak terjadi
penukaran dalam suatu iterasi.

Keuntungan lain dari algoritma ini adalah dapat dijalankan dengan cukup
cepat dan efisien untuk mengurutkan list yang urutannya sudah hampir
benar.
Selain kasus terbaik tersebut, komleksitas untuk algoritma ini adalah
O(n²).
Karenanya algoritma ini termasuk sangat tidak efisien untuk dilakukan,
apalagi jika pengurutan dilakukan terhadap elemen yang banyak jumlahnya.
Biasanya bubble sort digunakan untuk mengenalkan konsep dari sorting
algoritma pada pendidikan komputer karena idenya yang cukup sederhana.

Buble sort membandingkan elemen sekarang dengan elemen berikutnya.


Ketika satu proses selesai, maka bublesort akan mengulangi proses, begitu
seterusnya. Dan hanya berhenti saat semua data selesai diperiksa dan tidak
ada pertukaran lagi yang bisa dilakukan. Implementasi dari bublesort adalah
sederhana, tetapi lambat.

Kompleksitas bubble sort


Algoritma di dalam bubble sort terdiri dari 2 kalang (loop) bertingkat. Kalang
pertama berlangsung selama N-1 kali. Indeks untuk kalang pertama adalah
Pass. Kemudian kalang tingkat kedua berlangsung dari N sampai dengan
Pass+1. Dengan demikian, proses compare yang terjadi sebanyak:

T(n)=(N-1)+(N-2)+….+2+1

n-1
=∑ N-I = N(N-1)/2
I=1

T(n) = N(N-1)/2= O(n2)


T(n) ini merupakan kompleksitas untuk kasus terbaik ataupun terburuk.
Hanya saja pada kasus terbaik, yaitu pada kasus jika struktur data telah
terurut sesuai perintah, proses Pass terjadi tanpa adanya assignment. Hal ini
jelas menunjukkan bahwa algoritma akan berjalan lebih cepat. Hanya saja
tidak terlalu signifikan. menurut Wikipedia2, algoritma bubble sort, jika
dikembangkan, kompleksitasnya mencapai Ω(n) . Hal ini hanya terjadi jika
memanfaatkan tipe data boolean untuk menyatakan bahwa proses
penukaran tak perlu dilakukan lagi. Dengan demikian, kompleksitas Ω(n)
tidak berlaku bagi pseudocode di atas. Untuk itu perlu dilakukan perubahan.
Perubahan yang terjadi pada pseudocode-nya dapat diperhatikan sebagai
berikut:
Procedure BubbleSort (Input/Output
T: TabInt, Input N: integer)
{mengurut tabel integer [1 .. N]
dengan Bubble Sort dengan memanfaatkan
boolean}
Kamus:
i: integer
Pass: integer
Temp: integer
Tukar: boolean
Algoritma:
Pass 1
Tukar true
while (Pass ≤ N-1) and (Tukar) do
Tukar false
i traversal [N..Pass+1]
if (Ti < Ti-1) then
Temp Ti
Ti Ti-1
Ti-1 Temp
Tukar true
{T[1..Pass] terurut}

Dengan demikian ketika Pass terjadi sekali melalui semua bagian struktur
data, kemudian ditemukan bahwa tidak diperlukan lagi proses penukaran
elemen, maka proses pass akan berhenti. Bubble sort hanya melakukan N-1
perbandingan di dalam algoritmanya dan menetapkan bahwa struktur data
telah terurut. Dengan demikian, ( ) ( ) min T n = N = O n Sementara ( ) max
T n nya tetap sama. Bubble sort tergolong algoritma yang paling tidak efisien
di antara algoritma sorting dengan kompleksitas O(n2 ). Berikut ini adalah
data analisis empiris efisiensi Bubble Sort.

Berdasarkan tabel, tidak ada perbedaan performansi secara signifikan untuk


pengurutan terhadap 100 item atau kurang. Namun, bubble sort tidak
disarankan untuk pengurutan yang terus berulang, atau pengurutan yang
menangani lebih dari 200 item.

3. Merge sort

Merge (Quicksort) Sort memanfaatkan proses rekursi (pemanggilan diri sendiri)


sampai habis. Prinsip
metode ini membagi data menjadi dua bagian yang sama (kiri dan kanan), dimana
data tengah (mid/ pivot) menjadi pusat operasi. Jika data dikiri lebih kecil dari mid,
maka pisahkan kekiri. Jika data dikanan lebih besar daripada mid, maka pisahkan ke
kanan. Begitu seterusnya. Meskipun metode ini cepat, akan tetapi mplementasinya
agak rumit.

Pola Divide and Conquer


Beberapa algoritma mengimplementasikan konsep rekursi untuk
menyelesaikan permasalahan. Permasalahan utama kemudian dipecah
menjadi sub-masalah, kemudian solusi dari sub-masalah akan membimbing
menuju solusi permasalahan
Pada setiap tingkatan rekursi, pola tersebut terdiri atas 3 langkah.
1. Divide
Memilah masalah menjadi sub masalah
2. Conquer
Selesaikan sub masalah tersebut secara rekursif. Jika sub-masalah tersebut
cukup ringkas dan sederhana, pendekatan penyelesaian secara langsung
akan lebih efektif
3. Kombinasi
Mengkombinasikan solusi dari sub-masalah, yang akan membimbing menuju
penyelesaian atas permasalahan utama