Pengurutan 2: merge sort dan quicksort
Mengurutkan sejuta nilai dengan membandingkan setiap pasangan butuh sekitar 500 miliar perbandingan; merge sort hanya butuh sekitar 20 juta.
Pecah masalahnya, selesaikan tiap separuh
Metode di unit sebelumnya bekerja pada seluruh daftar sekaligus dan harus membayarnya dengan sekitar n² perbandingan. Dua metode di unit ini memakai rencana lain yang disebut divide and conquer (bagi dan taklukkan). Pecah daftar menjadi bagian-bagian yang lebih kecil, urutkan setiap bagian dengan metode yang sama, lalu gabungkan bagian-bagian yang sudah terurut. Pemecahan berlanjut sampai sebuah bagian hanya berisi satu nilai atau kosong, dan daftar berisi satu nilai pasti sudah terurut. Karena metode ini memanggil dirinya sendiri pada daftar yang lebih kecil, metode ini bersifat rekursif (unit 6 membahas rekursi lebih rinci).
Merge sort: kerjanya ada pada penggabungan
Merge sort memotong daftar menjadi dua, mengurutkan separuh kiri, mengurutkan separuh kanan, lalu menggabungkan kedua separuh yang terurut menjadi satu. Bagian cerdiknya ada pada penggabungan. Dua daftar terurut bisa digabungkan hanya dengan melihat nilai terdepannya. Bandingkan kedua nilai terdepan, tuliskan yang lebih kecil, lalu lewati nilai itu. Ulangi sampai salah satu daftar kosong, lalu salin sisa daftar yang lain. Penggabungan [1, 4, 7] dan [2, 3, 8] berjalan 1 (1 lawan 2), 2 (4 lawan 2), 3 (4 lawan 3), 4 (4 lawan 8), 7 (7 lawan 8), lalu 8 disalin: 5 perbandingan untuk 6 nilai. Penggabungan dua daftar yang seluruhnya berisi n nilai tidak pernah butuh lebih dari n − 1 perbandingan.
function merge(left, right) {
const out = [];
let i = 0, j = 0;
while (i < left.length && j < right.length) {
if (right[j] < left[i]) out.push(right[j++]);
else out.push(left[i++]);
}
return out.concat(left.slice(i), right.slice(j));
}
function mergeSort(a) {
if (a.length <= 1) return a; // sudah terurut
const mid = Math.floor(a.length / 2);
return merge(mergeSort(a.slice(0, mid)), mergeSort(a.slice(mid)));
}Mengapa ini cepat? Bayangkan pembagian dua itu sebagai tingkat-tingkat. Daftar berisi 8 nilai terpecah menjadi 2 daftar berisi 4, lalu 4 daftar berisi 2, lalu 8 daftar berisi 1: tiga tingkat, karena 8 bisa dibagi dua sebanyak 3 kali. Di setiap tingkat, semua penggabungan bersama-sama menyentuh setiap nilai satu kali, jadi satu tingkat paling banyak memakan sekitar n perbandingan. Dengan log₂ n tingkat, jumlahnya sekitar n log₂ n. Untuk sejuta nilai, itu sekitar 20 juta perbandingan, dibandingkan sekitar 500 miliar untuk metode yang membandingkan pasangan demi pasangan. Jika dipecah menjadi [38, 27, 43, 3] dan [9, 82, 10], seperti di laboratorium, daftar [38, 27, 43, 3, 9, 82, 10] butuh 14 perbandingan; kode di atas memecahnya menjadi 3 dan 4 dan butuh 13.
Harganya adalah memori. Penggabungan butuh tempat untuk menulis hasilnya, jadi merge sort memakai daftar kedua yang sama besar dengan masukannya. Merge sort juga stabil: nilai-nilai yang sama besar tetap dalam urutan aslinya, karena penggabungan mengambil dari daftar kiri saat kedua nilai terdepan sama. Hal ini penting saat kamu mengurutkan tabel menurut satu kolom lalu kolom lain, misalnya menurut kota lalu menurut nama.
Seret untuk memutar. Gulir atau cubit untuk memperbesar.
Quicksort: pecah di sekitar pivot
Quicksort memecah daftar dengan cara yang berbeda. Metode ini memilih satu nilai, yaitu pivot, lalu menyusun ulang daftar sehingga semua yang lebih kecil daripada pivot berada di depannya dan sisanya di belakangnya. Langkah ini disebut partisi. Sekarang pivot sudah berada di tempat akhirnya, dan kedua sisi bisa diurutkan terpisah dengan metode yang sama. Tidak ada yang perlu digabungkan sesudahnya, karena setiap nilai di kiri sudah lebih kecil daripada setiap nilai di kanan.
Laboratorium ini memakai versi buku pelajaran yang umum, yang mengambil nilai terakhir setiap bagian sebagai pivot. Pada [5, 1, 4, 2, 8] pivot 8 dibandingkan dengan empat nilai lain yang semuanya lebih kecil, jadi 8 tetap di ujung. Bagian berikutnya, [5, 1, 4, 2], memakai pivot 2: hanya 1 yang lebih kecil, jadi setelah dua pertukaran daftarnya menjadi [1, 2, 4, 5, 8]. Satu perbandingan lagi menyelesaikan [4, 5]. Jumlahnya: 8 perbandingan dan 2 pertukaran.
Kalau pivot jatuh di dekat tengah, setiap pemecahan membagi dua masalahnya dan quicksort butuh sekitar n log₂ n perbandingan, seperti merge sort. Metode ini juga bekerja di dalam daftar asli tanpa salinan kedua. Namun pivot yang buruk merugikan. Kalau daftarnya sudah terurut dan pivot selalu nilai terakhir, setiap pemecahan hanya melepas satu nilai, dan quicksort kembali ke sekitar n²/2 perbandingan: 10 untuk [1, 2, 3, 4, 5], sama dengan selection sort. Pustaka sungguhan menghindarinya dengan memilih pivot lebih hati-hati, misalnya secara acak atau sebagai nilai tengah dari tiga nilai sampel.
| Metode | Perbandingan | Memori tambahan |
|---|---|---|
| Insertion sort | biasanya sekitar n²/4, terburuk sekitar n²/2 | tidak ada; stabil |
| Merge sort | sekitar n log₂ n, selalu | daftar kedua berisi n nilai; stabil |
| Quicksort | biasanya sekitar n log₂ n, terburuk sekitar n²/2 (pivot buruk) | sedikit; versi yang biasa tidak stabil |
| divide and conquer (bagi dan taklukkan) | Pecah masalah, selesaikan bagian-bagiannya dengan cara yang sama, gabungkan hasilnya |
| merge (penggabungan) | Menggabungkan dua daftar terurut dengan berulang kali mengambil nilai terdepan yang lebih kecil |
| merge sort | Bagi dua, urutkan tiap separuh, gabungkan: sekitar n log₂ n perbandingan |
| pivot | Nilai yang menjadi titik pemecahan daftar dalam quicksort |
| partisi (partition) | Menyusun ulang sehingga nilai yang lebih kecil berada di depan pivot dan sisanya di belakang |
| quicksort | Partisi di sekitar pivot, lalu urutkan setiap sisi |
| pengurutan stabil (stable sort) | Nilai yang sama tetap dalam urutan aslinya |
| in place (di tempat) | Mengurutkan di dalam daftar asli dengan sedikit memori tambahan |
- Berapa perbandingan yang dibutuhkan untuk menggabungkan [1, 4, 7] dan [2, 3, 8]?
- Berapa perbandingan yang dibutuhkan untuk menggabungkan [1, 2, 3] dan [4, 5, 6]?
- Daftar berisi 16 nilai dibagi dua terus sampai setiap bagian berisi satu nilai. Ada berapa tingkat pembagian?
- Kira-kira berapa perbandingan yang dilakukan merge sort pada sejuta nilai?
- sekitar 20
- sekitar 20 juta
- sekitar 500 miliar
- tepat sejuta
- Setelah partisi, di mana letak pivot?
- Di posisi akhirnya dalam urutan
- Di depan
- Di ujung
- Di mana saja; nanti pivot berpindah lagi
- Quicksort dengan nilai terakhir sebagai pivot dijalankan pada daftar yang sudah terurut [1, 2, 3, 4, 5]. Berapa perbandingan yang dilakukannya?
- Metode mana yang butuh daftar kedua sebesar masukannya?
- Merge sort
- Quicksort
- Insertion sort
- Siapa yang mengusulkan merge sort pada 1945?
- Tony Hoare
- John von Neumann
- Ada Lovelace
- Euclid
- Masalah apa yang membawa Tony Hoare ke quicksort?
- Mengurutkan kata-kata dalam kalimat untuk kamus di pita magnetik
- Mengurutkan buku perpustakaan
- Memeringkat halaman web
- Mengurutkan cek bank
- Mengapa merge sort disebut stabil?
- Nilai yang sama tetap dalam urutan aslinya
- Tidak pernah macet
- Waktunya selalu sama
- Tidak memakai memori tambahan
- Berapa jumlah perbandingan kasus terburuk sekecil-kecilnya untuk pengurutan berbasis perbandingan apa pun pada 10 nilai (log₂ 10!, dibulatkan ke atas)?
- Divide and conquer: pecah, selesaikan bagian-bagiannya, gabungkan.
- Merge sort: selalu sekitar n log₂ n perbandingan, butuh memori tambahan, stabil.
- Quicksort: partisi di sekitar pivot; rata-rata cepat, sekitar n²/2 kalau pivotnya buruk.
- Sejuta nilai: sekitar 20 juta perbandingan, bukan 500 miliar.
- Tidak ada pengurutan berbasis perbandingan yang bisa mengalahkan sekitar n log₂ n dalam kasus terburuk.
Sumber kursus ini (11)
- MIT OpenCourseWare 6.006 Introduction to Algorithms, Spring 2020 (Demaine, Ku, Solomon)
- lecture notes 1 Introduction, 3 Sorting, 9 Breadth-First Search, 10 Depth-First Search (ocw.mit.edu/courses/6-006-introduction-to-algorithms-spring-2020/pages/lecture-notes) and Fall 2011 lecture 13 BFS notes (ocw.mit.edu/courses/6-006-introduction-to-algorithms-fall-2011)
- Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms (MIT Press)
- with the CLRS-based Khan Academy algorithms unit by Thomas Cormen and Devin Balkcom of Dartmouth (khanacademy.org/computing/computer-science/algorithms: binary search, selection sort analysis, merge sort, quicksort overview and analysis)
- MacTutor History of Mathematics, Al-Khwarizmi (mathshistory.st-andrews.ac.uk/Biographies/Al-Khwarizmi: word algorithm from the Latin title Algoritmi de numero Indorum)
- D. E. Joyce, Euclid's Elements Book VII Propositions 1 and 2 (mathcs.clarku.edu/~djoyce/elements/bookVII)
- Wolfram MathWorld, Merge Sort (mathworld.wolfram.com/MergeSort.html: proposed by John von Neumann in 1945, after Knuth 1998 p. 159)
- Stanford CS "Tony Hoare: Quicksort" (cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/tony-hoare/quicksort.html: devised while a student at Moscow State University for Russian-English machine translation with a tape dictionary, programmed in Algol 60 and published 1961; the year 1959 from the Wikipedia Quicksort article and its cited sources)
- Bodleian Libraries, Ada Lovelace (blogs.bodleian.ox.ac.uk/adalovelace: 1843 paper, Note G Bernoulli numbers)
- Fourmilab text of Menabrea's Sketch with Lovelace's notes (fourmilab.ch/babbage/sketch.html)
- Seven Bridges of Konigsberg (Euler 1736) and Tower of Hanoi (Edouard Lucas, 1883) checked against the Wikipedia articles and their cited sources.
Diperiksa: 2026-10-17