Anda di halaman 1dari 20

Algoritma Sorting adalah kumpulan langkah sistematis atau secara berutan untuk

memperoleh hasil yang diinginkan. Salah satu contoh dari algoritma untuk langkah ini
adalah Sorting (pengurutan). Sorting dapat didefinisikan sebagai pengurutan sejumlah
data berdasarkan nilai tertentu. Pengurutan dapat dilakukan dari nilai terkecil ke nilai
terbesar (ascending) atau sebaliknya.

Jenis-jenis algoritma pengurutan nilai yang akan dibahas pada makalah ini adalah merge sort
(pengurutan dengan penggabungan), quick sort (pengurutan cepat), heap sort (pengurutan
dengan tumpukan), counting sort (pengurutan dengan mencacah), radix sort (pengurutan
tanpa perbandingan).

1. Pengurutan Dengan Penggabungan (Merge Sort)

Algoritma merge sort membagi (split) tabel menjadi dua tabel sama besar. Masing-masing tabel
diurutkan secara rekursif, dan kemudian digabungkan kembali untuk membentuk tabel yang
terurut.
Implementasi dasar dari algoritma merge sort memakai tiga buah tabel, dua untuk menyimpan
elemen dari tabel yang telah dibagi dua dan satu untuk menyimpan elemen yang telah teurut.
Namun algoritma ini dapat juga dilakukan langsung pada dua tabel, sehingga menghemat ruang
atau memori yang dibutuhkan. Di bawah ini adalah algoritma untuk merge sort yang dilakukan
pada dua tabel.
Contoh Program Merge Sort
#include<iostream>
using namespace std;
int a[50];
void merge(int, int, int);
void merge_sort(int low, int high)
{
int mid;

if (low < high)


{
mid = (low + high)/2;
merge_sort(low, mid);
merge_sort(mid + 1, high);
merge(low, mid, high);
}
}
void merge(int low, int mid, int high)
{
int h, i, j, b[50], k;
h = low;
i = low;
j = mid + 1;

while ((h <= mid) && (j <= high))


{
if (a[h] <= a[j])
{
b[i] = a[h];
h++;
}
else
{
b[i] = a[j];
j++;
}
i++;
}
if (h > mid)
{
for (k = j; k <= high; k++)
{
b[i] = a[k];
i++;
}
}
else
{
for (k = h; k <= mid; k++)
{
b[i] = a[k];
i++;
}
}
for (k = low; k <= high; k++)
a[k] = b[k];
}

int main()
{
int num, i;

cout << "Tuan, Silahkan masukkan banyaknya data yang akan diurut : ";
cin >> num;
cout << endl;
cout << "Tuan, Silahkan masukkan " << num << " data: " << endl;

for (i = 1; i <= num; i++)


{
cin >> a[i];
}
merge_sort(1, num);
cout << endl;

cout << "Setelah Pengurutan (Merge Sort) : " << endl;


for (i = 1; i <= num; i++)
cout << a[i] << " ";
return 0;
}

Output Program Merge Sort

Algoritma merge sort ini sebenernya lebih cepat dibandingkan heap sort untuk tabel yang lebih
besar. Namun, algoritma ini membutuhkan setidaknya ruang atau memori dua kali lebih besar
karena dilakukan secara rekursif dan memakai dua tabel. Hal ini menyebabkan algoritma ini
kurang banyak dipakai.
Kesimpulan
Merge Sort adalah metode pengurutan data dengan cara data dibagi menjadi subkumpulan -
subkumpulan yang kemudian subkumpulan tersebut diurutkan secara terpisah, dan kemudian
digabungkan kembali dengan metode merging
1. Pengurutan Cepat (Quick Sort)

Algoritma quick sort sangat sederhana dalam teori, tetapi sangat sulit untuk diterjemahkan ke
dalam sebuah code karena pengurutan dilakukan dalam sebuah list dan diproses secara rekursif.
Algoritma ini terdisi dari tiga langkah (yang mana menyerupai merge sort) yaitu :

1. Memilih sebuah elemen untuk dijadikan poros atau pivot point (biasanya elemen paling
kiri dari tabel).
2. Membagi tabel menjadi dua bagian, satu dengan elemen yang lebih besar dari poros,
dan satu lagi untuk elemen yang lebih kecil dari poros.
3. Mengulang algoritma untuk kedua buah tabel secara rekursif.

Tingkat keefektifan dari algoritma ini dangat bergantung pada elemen yang dipilih menjadi
poros. Kasus terburuk terjadi ketika tabel sudah terurut dan elemen terkecil di sebelah kiri
menjadi poros. Kasus ini mempunyai kompleksitas algoritma O(n2). Maka dari itu sangat
disarankan untuk memilih poros bukan dari elemen paling kiri dari tabel, tetapi dipilih secara
random. Selama poros dipilih secara random, algoritma quick sort mempunyai kompleksitas
algoritma sebesar O(n log n).

Ilustrasi Pengurutan Cepat (Quick Sort)

Contoh Program Quick Sort


#include<iostream>

using namespace std;

void tampilkan_array(int data[], int n)


{
int i;
for (i = 0; i < n; i++)
cout << data[i] << " ";
cout << endl;
}

int partisi(int data[], int p, int r)


{
int x, i, j, temp;

x = data[p];
i = p;
j = r;
while (1)
{
while (data[j] > x)
j = j - 1;
while (data[i] < x)
i = i + 1;
if (i < j)
{
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
else
return j;
}
}

void quick_sort(int data[], int p, int r)


{
int q;
if (p < r)
{
q = partisi(data, p, r);
quick_sort(data, p, q);
quick_sort(data, q+1, r);
}
}
int main()
{
int jum_data = 10;
int i;
int data[] = { 101, 199, 200, 121, 124, 122, 126, 167, 132, 111 };

quick_sort(data, 0, jum_data - 1);


cout << "Hasil Pengurutan Quick Sort \n";
tampilkan_array(data, jum_data);

return 0;
}

Output Program Quick Sort

Kesimpulan
Quick sort merupakan algoritma yang mempartisi banyaknya data yang dimasukan untuk
mempercepat proses. Dimana inputan yang dimasukan adalah n buah masukan. Algoritma ini
memiliki kompleksitas saat kondisi teburuk (worst case) Tn=O(n2) dan kondisi terbaik (best
case) Tn= O(n 2log n).
Beberapa hal yang membuat quick sort unggul:
Secara umum memiliki kompleksitas O(n log n).
Algoritmanya sederhana dan mudah diterapkan pada berbagai bahasa pemrograman dan
arsitektur mesin secara efisien.
Dalam prakteknya adalah yang tercepat dari berbagai algoritma pengurutan dengan
perbandingan, seperti merge sort dan heap sort.
Melakukan proses langsung pada input (in-place) dengan sedikit tambahan memori.
Bekerja dengan baik pada berbagai jenis input data (seperti angka dan karakter).
Namun terdapat pula kelemahan quick sort:
Sedikit kesalahan dalam penulisan program membuatnya bekerja tidak beraturan (hasilnya
tidak benar atau tidak pernah selesai).
Memiliki ketergantungan terhadap data yang dimasukkan, yang dalam kasus terburuk memiliki
kompleksitas O(n2).
Secara umum bersifat tidak stable, yaitu mengubah urutan input dalam hasil akhirnya (dalam
hal inputnya bernilai sama).
Pada penerapan secara rekursif (memanggil dirinya sendiri) bila terjadi kasus terburuk dapat
menghabiskan stack dan memacetkan program.
3. Heap Sort (Pengurutan Dengan Tumpukan)

Heap sort adalah algoritma yang paling lambat daripada algoritma yang memiliki
kompleksitas 0(n long n) lebih unggul daripada algoritma marge sort dan quick sort karena
tidak memerlukan rekursif yang besar. Untuk itu heap sort sangatlah cocok sebuah kumpulan
data yang besar.
Algoritma ini bekerja dengan menentukan elemen terbesar atau elemen terkecil dari sbuah
daftar element, yang kemudian diletakkan di akhir atau di awal dari daftar tersebut.
Algoriyma ini diawali dengan membuat array heap dgn membangun tumpukan dari kumpulan
data kemudian memindahkan data dari terbesar ke bagian belakang dari sebuah table hasil,
kemudian array heap tersebut dibangun kembali untuk mengambil elemen terbesar yang
kemudian diletakkan di sebelah item yang telah dipindahkan tadi. Hal ini diulang-ulang sampai
array heap habis.
Jadi kebanyakan metode ini memerlukan 2 buah table, satu tabel untuk menyimpan heap dan
tabel yang lain untuk menyimpan hasil.
Contoh Program Heap Sort
#include <iostream>
#include <conio.h>
using namespace std;
void max_heapify(int *a, int i, int n)
{
int j, temp;
temp = a[i];
j = 2 * i;
while (j <= n)
{
if (j < n && a[j + 1] > a[j])
j = j + 1;
if (temp > a[j])
break;
else if (temp <= a[j])
{
a[j / 2] = a[j];
j = 2 * j;
}
}
a[j / 2] = temp;
return;
}
void heapsort(int *a, int n)
{
int i, temp;
for (i = n; i >= 2; i--)
{
temp = a[i];
a[i] = a[1];
a[1] = temp;
max_heapify(a, 1, i - 1);
}
}
void build_maxheap(int *a, int n)
{
int i;
for (i = n / 2; i >= 1; i--)
{
max_heapify(a, i, n);
}
}

int main()
{
int n, i, x;
cout << "Tuan, Silahkan masukkan banyaknya data yang akan diurut : \n";
cin >> n;
int a[20];
for (i = 1; i <= n; i++)
{
cout << "Masukkan Data " << (i) << endl;
cin >> a[i];
}
build_maxheap(a, n);
heapsort(a, n);
cout << "Hasil Pengurutan melalui Heap Sort \n";
for (i = 1; i <= n; i++)
{
cout << a[i] << endl;
}
getch();
}
Output Program Heap Sort

Kesimpulan
Dengan memanfaatkan struktur data pohon, kita bisa mendapatkan algoritma pengurutan data
yang mangkus yang bisa dimanfaatkan untuk membangun program aplikasi yang baik.
Algoritma pengurutan heap sort bisa dimasukkan ke dalam algoritma divide and conquer yang
disebabkan pembagian dilakukan dengan terlebih dahulu menerapkan algoritma metoda
heapify sebagai inisialisasi untuk mentransformasi suatu tree menjadi heap tree, dan pada setiap
tahapan diterapkan algoritma metoda reheapify untuk menyusun ulang heap tree.

4. Pengurutan dengan Mencacah (Count Sort)

Pengurutan dengan mencacah adalah pengurutan yang paling sederhana. Jika diketahui bahwa
tabel yang akan diurutkan nilainya mempunyai daerah atau range tertentu dan merupakan
bilangan bulat, misalnya [ElMin..ElMax] maka cara paling sederhana untuk mengurut adalah
:
 Sediakan tabel TabCount [ElMin..Elmax] yang diinisialisasi dengan nol, dan pada akhir
proses TabCount[i] berisi banyaknya elemen pada tabel asal T yang berharga i;
 Tabel asal T dibentuk kembali dengan menuliskan harga-harga yang ada dengan jumlah
sesuai dengan yang ada pada TabCount.

Counting Sort adalah salah satu metode mengurutkan data yang dikenal. Ide dasarnya adalah
seperti kita melakukan perhitungan pemilu yaitu dengan mencatat frekuensi atau banyaknya
kemunculan data. Namun metode ini hanya cocok digunakan bila data yang digunakan bertipe
integer dan dibatasi pada range tertentu. Namun menurut opini pribadi saya, cara ini termasuk
tidak terlalu efisien dan “menyenangkan”. Apalagi untuk bahasa Pascal. Kenapa? Untuk
mennggunaan metode ini kita harus membuat larik baru dengan range antara nilai minimum
dan maksimum. Ya, kalo misal nilai minimum kita adalah 0 dan maksimum kita adalah 100
maka kita harus mendeklarasikan larik / array sebanyak 100 elemen (dari nilai minimum hingga
nilai maksimum).

Contoh Program Counting Sort


#include <iostream>
using namespace std;
void print(int a[], int sz) {
for (int i = 0; i < sz; i++ ) cout << a[i] << " ";
cout << endl;}
void CountingSort(int arr[], int sz) {
int i, j, k;
int idx = 0;
int min, max;
min = max = arr[0];
for(i = 1; i < sz; i++) {
min = (arr[i] < min) ? arr[i] : min;
max = (arr[i] > max) ? arr[i] : max;
}
k = max - min + 1;
/* creates k buckets */
int *B = new int [k];
for(i = 0; i < k; i++) B[i] = 0;
for(i = 0; i < sz; i++) B[arr[i] - min]++;
for(i = min; i <= max; i++)
for(j = 0; j < B[i - min]; j++) arr[idx++] = i;
print(arr,sz);
delete [] B;}
int main()
{
int a[] = {5,9,3,9,10,9,2,4,13,10};
const size_t sz = sizeof(a)/sizeof(a[0]);
print(a,sz);
cout << "----------------------\n" ;
CountingSort(a, sz);}

Output Program Counting Sort


Cara kerja Program Counting Sort

Syarat agar pengurutan ini dapat dilakukan adalah diketahuinya rentang nilai data-datanya.
Data-data yang akan diurutkan juga harus berupa bilangan bulat (integer). Counting sort bisa
efisien bila k tidak jauh lebih besar daripada n. Di mana semakin besar k maka memori
tambahan yang diperlukan menjadi sangat besar. Contoh di mana counting sort dapat menjadi
efisien adalah bila mengurutkan siswa-siswa dalam sebuah sekolah berdasar nilainya, dengan
nilai adalah bilangan bulat dengan rentang 0..100. Dan contoh dimana counting sort akan
sangat buruk kinerjanya adalah untuk data yang rentangnya sangat besar, misal dengan rentang
0..232-1.

Counting sort memiliki properti yang penting, yaitu ke-stable-an. Di mana data-data dengan
nilai yang sama akan diurutkan berdasar urutan kemunculan pada array asal. Properti ini sangat
penting dalam pengurutan data majemuk. Dengan kompleksitas O(n), metode pengurutan ini
sangat cepat dan efektif. Yang diimbangi dengan kelemahan yaitu dibutuhkan memori
tambahan sebagai array bantu dalam prosesnya.

Jika pengurutan dengan mencacah dijalankan pada element integer berukuran 32 bit, maka
kasus terbaik terjadi berisi satu jenis element. Kasus terburuk terjadi ketika kmin bernilai -232
dan kmax bernilai 232. Loop 1 dan Loop 3 mempunyai O(k). Loop 2 dan Loop 4 mempunyai
O(n). Sehingga dapat dijabarkan sebagai berikut:

T(n) = O(k) + O(n) + O(k) + O(n)


= O(k) + O(k) + O(n) + O(n)

= O(k) + O(n)

= O(k+n)

= O(n)

Dengan contoh dan algoritma yang telah dibahas, jelas bahwa counting sort melakukan
pengurutan tanpa melakukan perbandingan antar data.

Kesimpulan

Untuk melakukan pengurutan nilai ynag paling sederhana dan paling mudah dimengerti adalah
algoritma counting sort namun algoritma ini tidak efektif digunakan pada tabel dengan range
yang besar. Dimana semakin besar k, maka kebutuhan memori menjadi sangat besar. Secara
lebih mendalam, Counting Sort adalah algoritma pengurutan efektif dan efisien yang
melakukan pengurutan dengan ide dasar meletakkan elemen pada posisi yang benar, di mana
penghitungan posisi yang benar dilakukan dengan cara menghitung (counting) elemen-elemen
dengan nilai lebih kecil atau sama dengan elemen tersebut. Dan memiliki kompleksitas
waktu linier O(n). Walaupun tidak dapat digunakan secara luas karena banyaknya batasan.

5. Pengurutan Tanpa Perbandingan (Radix Sort)

Algoritma radix sort adalah salah satu algoritma pengurutan yang paling mangkus karena tidak
menggunakan perbandingan secara langsung. Untuk kasus bilangan bulat (integer), algoritma
ini akan mengurutkan data dengan mengelompokkan data-data berdasarkan digit yang
memiliki significant position dan value yang sama. Kelompok digit ini ditampung dalam suatu
variable “bucket”. Struktur datanya direpresentasikan dengan array. Algoritma ini pertama kali
diperkenalkan pada tahun 1887 oleh Herman Hollerith pada mesin tabulasi.

Ada dua jenis radix sort saat ini :

- LSD (least significant digit) radix sort, yaitu radix sort yang mengurutkan data dimulai dari
digit terkecil. Algoritma ini cenderung stabil karena tetap mengikuti urutan awal data-data
sebelum diurutkan.
- MSD (most significant digit) radix sort, yaitu radix sort yang mengurutkan data dimulai dari
digit terbesar. Algoritma ini lebih susah untuk direalisasikan daripada LSD radix sort, dan
biasanya tidak mengikuti urutan awal data-data yang akan diurutkan.

Makalah ini hanya akan membahas LSD radix sort.

Misalkan terdapat sebuah array dengan elemen “121 76 823 367 232 434 742 936 274”. Dengan
menggunakan algoritma radix short :

Pertama kali data dibagi-bagi sesuai dengan digit terkanan :

Pada saat penentuan kategori lihat terlebih dahulu nilai digit yang terbesar dicontoh ini yakni
nilai digit yang terbesar 9 sehingga kategori sebanyak 9 baris dan diawali dari 0. Langsung aja
supaya lebih jelas perhatikan tabel dibawah ini :

Hasil pengkategori pertama kemudian digabungkan kembali menurut penjelasan yang diatas:

Kemudian dilakukan pengkategorian kembali berdasarkan digit yang kedua dengan


berpatokan(melihat) baris urutan pengkategorian pertama yaitu :
Selanjutnya hasil pengkategori kedua digabungkan kembali.

Kemudian langkah ketiga (terakhir), dilakukan pengkategorian kembali berdasar digit ketiga.
dengan berpatokan (melihat) baris urutan pengkategorian kedua yaitu :

Jadi, hasil akhirnya dapat dituliskan :

Dari langkah-langkah yang telah dilakukan dalam proses pengurutan menggunakan radix sort,
jelas tampak bahwa radix sort termasuk algoritma pengurutan tanpa pembanding. Dengan
sifatnya yang melihat digit-digit angka sebagai pengontrolnya, Radix Sort dapat
diimplementasikan dalam pengurutan bilangan desimal dan bilangan bit. Namun dalam
penggunaannya radix sort bisa dimodifikasi sehingga bisa digunakan untuk menggurutkan data
data negatif dan pecahan.

Kelebihan dan Kekurangan Redix Short

Algoritma radix sort memiliki kelebihan dan kekurangan yang berbeda dibandingkan dengan
algoritma pengurutan yang lain. Beberapa kelebihan algoritma radix sort adalah sebagai berikut
:

- Algoritma sangat mangkus. Hal ini dapat dilihat dari kompleksitas waktu asimptotiknya yang
sangat kecil (O(kN)). Hal ini mengakibatkan algoritma radix sort sangat efektif untuk data
dalam jumlah yang sangat besar sekalipun.

- Konsep algoritma mudah dipahami. Algoritma radix sort mengurutkan data berdasarkan digit,
tidak melalui proses perbandingan yang cenderung sulit dipahami.

Walaupun memiliki banyak kelebihan dibandingkan algoritma pengurutan yang lain, algoritma
ini memiliki kekurangan : realisasi program rumit dan kurang fleksibel untuk digunakan pada
tipe data lain.

Realisasi program untuk algoritma radix sort tidak semudah memahami konsep dasarnya.
Secara umum, algoritma ini membutuhkan bucket untuk mengelompokkan data-data yang
sedang diurutkan. Inisialisasi bucket untuk kasus ini tidak mudah dilakukan. Pada awalnya,
radix sort hanya dapat digunakan untuk data bertipe bit dan desimal. Tetapi, seiring waktu,
radix sort mulai dikembangkan untuk tipe data yang lain. Saat ini radix sort sudah dapat
digunakan untuk tipe data berupa bilangan pecahan dan bilangan negatif. Akan tetapi,
modifikasi terhadap algoritma ini menjadi signifikan. Pada umumnya, pengembangan
algoritma radix sort untuk tipe data lain dibantu dengan menggunakan counting sort, yang
merupakan salah satu algoritma pengurutan yang tidak menggunakan perbandingan. Penulis
tidak akan membahas algoritma ini mengingat batasan makalah yang diberikan.

Contoh Program Radix Sort


#include <stdio.h>
#define MAX 20
#define SHOWPASS
#define BASE 10
void print(int *a, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%d\t", a[i]);
}

void radixsort(int *a, int n)


{
int i, b[MAX], m = a[0], exp = 1;

//Get the greatest value in the array a and assign it to m


for (i = 1; i < n; i++)
{
if (a[i] > m)
m = a[i];
}

//Loop until exp is bigger than the largest number


while (m / exp > 0)
{
int bucket[BASE] = { 0 };

//Count the number of keys that will go into each bucket


for (i = 0; i < n; i++)
bucket[(a[i] / exp) % BASE]++;

//Add the count of the previous buckets to acquire the indexes after the end of
each bucket location in the array
for (i = 1; i < BASE; i++)
bucket[i] += bucket[i - 1]; //similar to count sort algorithm i.e.
c[i]=c[i]+c[i-1];

//Starting at the end of the list, get the index corresponding to the a[i]'s key,
decrement it, and use it to place a[i] into array b.
for (i = n - 1; i >= 0; i--)
b[--bucket[(a[i] / exp) % BASE]] = a[i];

//Copy array b to array a


for (i = 0; i < n; i++)
a[i] = b[i];

//Multiply exp by the BASE to get the next group of keys


exp *= BASE;

#ifdef SHOWPASS
printf("\nPASS : ");
print(a, n);
#endif
}
}
int main()
{
int arr[MAX];
int i, n;
printf("Enter total elements (n <= %d) : ", MAX);
scanf("%d", &n);
n = n < MAX ? n : MAX;

printf("Enter %d Elements : ", n);


for (i = 0; i < n; i++)
scanf("%d", &arr[i]);

printf("\nARRAY : ");
print(&arr[0], n);

radixsort(&arr[0], n);

printf("\nSORTED : ");
print(&arr[0], n);
printf("\n");

return 0;
}

Output Program Radix Sort

Kesimpulan

Algoritma radix sort melakukan pengurutan terhadap data berdasarkan digit (radix) dari data-
data yang sedang diproses.

Algoritma radix sort adalah salah satu algoritma tanpa perbandingan yang mangkus dan
sederhana untuk dipahami, tetapi rumit dalam realisasinya.
Algoritma radix sort dapat direpresentasikan dalam berbagai cara, terutama bagian bucket-nya.
Bucket data dapat direpresentasikan dalam bentuk array atau queue.

Algoritma radix sort dapat digunakan untuk tipe data selain bit dan desimal, tetapi diperlukan
bantuan algoritma pengurutan lain, seperti counting sort.

Anda mungkin juga menyukai