Mata Kuliah: Struktur Data dan Algoritma
Kode: SDA201
SKS: 3 SKS (2 Teori + 1 Praktikum)
Pertemuan: 09
Topik: Algoritma Sorting Dasar (Bubble Sort, Selection Sort, Insertion Sort)
Capaian Pembelajaran: Sub-CPMK-4.1 — Mampu mengimplementasikan algoritma sorting dasar dan menganalisis kompleksitasnya
Estimasi Waktu Belajar: 7 jam
Referensi Utama: Cormen Ch.2; Weiss Ch.7.2; Hubbard Ch.13
Setelah menyelesaikan modul ini, mahasiswa diharapkan mampu:
Definisi: Sorting (pengurutan) adalah proses menyusun ulang elemen-elemen dalam suatu koleksi data berdasarkan kriteria tertentu, biasanya dalam urutan ascending (menaik) atau descending (menurun).
Sorting merupakan salah satu operasi fundamental dalam ilmu komputer. Diperkirakan 25-50% waktu komputasi di banyak sistem dihabiskan untuk proses sorting. Mengapa? Karena data yang terurut memungkinkan:
Dalam memilih algoritma sorting, kita perlu mempertimbangkan beberapa kriteria:
| Kriteria | Deskripsi | Pertimbangan |
|---|---|---|
| Kompleksitas Waktu | Jumlah operasi yang dilakukan | Best, average, worst case |
| Kompleksitas Ruang | Memori tambahan yang dibutuhkan | In-place vs membutuhkan array tambahan |
| Stabilitas | Mempertahankan urutan elemen dengan nilai sama | Penting untuk sorting multi-key |
| Adaptivitas | Performa pada data yang hampir terurut | Beberapa algoritma lebih adaptif |
| Kesederhanaan | Kemudahan implementasi dan debugging | Trade-off dengan performa |

Gambar 9.1: Klasifikasi algoritma sorting berdasarkan berbagai kriteria
Algoritma sorting dapat diklasifikasikan berdasarkan:
Berdasarkan Metode:
Berdasarkan Kompleksitas:
Berdasarkan Memori:
Dalam sistem pertahanan, sorting digunakan secara ekstensif:
Soal: Jelaskan mengapa algoritma sorting penting dalam operasi sistem C4ISR (Command, Control, Communications, Computers, Intelligence, Surveillance, Reconnaissance)!
Penyelesaian:
Sistem C4ISR memproses data dalam jumlah besar dari berbagai sumber secara real-time. Sorting menjadi krusial karena:
Dengan sorting yang efisien, decision maker dapat mengakses informasi kritis lebih cepat, yang bisa menjadi perbedaan antara keberhasilan dan kegagalan misi.
Soal: Apa perbedaan antara comparison-based sorting dan non-comparison sorting? Berikan masing-masing satu contoh!
Penyelesaian:
| Aspek | Comparison-Based | Non-Comparison |
|---|---|---|
| Mekanisme | Membandingkan pasangan elemen untuk menentukan urutan | Menggunakan informasi struktural tentang data |
| Lower Bound | Ω(n log n) untuk worst case | Dapat mencapai O(n) |
| Fleksibilitas | Bekerja dengan data apapun yang bisa dibandingkan | Membutuhkan asumsi tentang data |
| Contoh | Quick Sort, Merge Sort | Counting Sort, Radix Sort |
Contoh Comparison-Based (Bubble Sort):
// Membandingkan arr[j] dengan arr[j+1]
if (arr[j] > arr[j+1]) {
swap(arr[j], arr[j+1]);
}
Contoh Non-Comparison (Counting Sort):
// Menghitung kemunculan setiap nilai, tanpa perbandingan langsung
count[arr[i]]++;
Comparison-based sorting lebih umum digunakan karena fleksibilitasnya, sedangkan non-comparison sorting sangat efisien untuk kasus khusus dengan range nilai terbatas.
Definisi: Bubble Sort adalah algoritma sorting sederhana yang bekerja dengan berulang kali menukar elemen bersebelahan jika urutannya salah. Elemen terbesar “menggelembung” (bubble) ke posisi akhir array pada setiap iterasi.
Bubble Sort mendapatkan namanya dari cara elemen terbesar bergerak ke akhir array seperti gelembung yang naik ke permukaan air.
Langkah-langkah:

Gambar 9.2: Visualisasi proses Bubble Sort pada array [64, 34, 25, 12, 22]
#include <iostream>
using namespace std;
void bubbleSort(int arr[], int n) {
// Outer loop: jumlah pass
for (int i = 0; i < n - 1; i++) {
// Inner loop: membandingkan pasangan bersebelahan
for (int j = 0; j < n - i - 1; j++) {
// Bandingkan dan tukar jika perlu
if (arr[j] > arr[j + 1]) {
// Swap menggunakan variabel temporary
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void cetakArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Array sebelum sorting: ";
cetakArray(arr, n);
bubbleSort(arr, n);
cout << "Array setelah sorting: ";
cetakArray(arr, n);
return 0;
}
Output:
Array sebelum sorting: 64 34 25 12 22 11 90
Array setelah sorting: 11 12 22 25 34 64 90
Bubble Sort dasar selalu melakukan n-1 pass, meskipun array sudah terurut. Kita dapat mengoptimasi dengan mendeteksi jika tidak ada swap yang terjadi dalam satu pass:
void bubbleSortOptimized(int arr[], int n) {
bool swapped;
for (int i = 0; i < n - 1; i++) {
swapped = false;
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
swapped = true;
}
}
// Jika tidak ada swap dalam pass ini, array sudah terurut
if (!swapped) {
cout << "Early termination at pass " << (i + 1) << endl;
break;
}
}
}
Keuntungan optimasi:
| Kasus | Kompleksitas Waktu | Kondisi |
|---|---|---|
| Best Case | O(n) | Array sudah terurut (dengan optimasi) |
| Average Case | O(n²) | Elemen tersebar acak |
| Worst Case | O(n²) | Array terurut terbalik |
Kompleksitas Ruang: O(1) — In-place algorithm
Analisis matematis:
Soal: Trace eksekusi Bubble Sort pada array [5, 3, 8, 4, 2] dan hitung jumlah perbandingan serta swap!
Penyelesaian:
Array awal: [5, 3, 8, 4, 2]
Pass 1: | Langkah | Perbandingan | Aksi | Array | |———|————–|——|——-| | 1 | 5 > 3? Ya | Swap | [3, 5, 8, 4, 2] | | 2 | 5 > 8? Tidak | - | [3, 5, 8, 4, 2] | | 3 | 8 > 4? Ya | Swap | [3, 5, 4, 8, 2] | | 4 | 8 > 2? Ya | Swap | [3, 5, 4, 2, 8] |
Perbandingan: 4, Swap: 3
Pass 2: | Langkah | Perbandingan | Aksi | Array | |———|————–|——|——-| | 1 | 3 > 5? Tidak | - | [3, 5, 4, 2, 8] | | 2 | 5 > 4? Ya | Swap | [3, 4, 5, 2, 8] | | 3 | 5 > 2? Ya | Swap | [3, 4, 2, 5, 8] |
Perbandingan: 3, Swap: 2
Pass 3: | Langkah | Perbandingan | Aksi | Array | |———|————–|——|——-| | 1 | 3 > 4? Tidak | - | [3, 4, 2, 5, 8] | | 2 | 4 > 2? Ya | Swap | [3, 2, 4, 5, 8] |
Perbandingan: 2, Swap: 1
Pass 4: | Langkah | Perbandingan | Aksi | Array | |———|————–|——|——-| | 1 | 3 > 2? Ya | Swap | [2, 3, 4, 5, 8] |
Perbandingan: 1, Swap: 1
Hasil Akhir: [2, 3, 4, 5, 8]
Ringkasan:
Soal: Apa output dari kode berikut?
int arr[] = {1, 2, 3, 4, 5};
int n = 5;
bool swapped = false;
for (int j = 0; j < n - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
swapped = true;
}
}
cout << "Swapped: " << (swapped ? "Yes" : "No");
Penyelesaian:
Output: Swapped: No
Penjelasan:
arr[j] > arr[j+1]swapped tetap falseSoal: Modifikasi Bubble Sort untuk mengurutkan array dalam urutan descending!
Penyelesaian:
#include <iostream>
using namespace std;
void bubbleSortDescending(int arr[], int n) {
bool swapped;
for (int i = 0; i < n - 1; i++) {
swapped = false;
for (int j = 0; j < n - i - 1; j++) {
// Ubah kondisi dari > menjadi <
if (arr[j] < arr[j + 1]) {
swap(arr[j], arr[j + 1]);
swapped = true;
}
}
if (!swapped) break;
}
}
int main() {
int arr[] = {64, 34, 25, 12, 22};
int n = 5;
cout << "Sebelum: ";
for (int i = 0; i < n; i++) cout << arr[i] << " ";
cout << endl;
bubbleSortDescending(arr, n);
cout << "Sesudah (Descending): ";
for (int i = 0; i < n; i++) cout << arr[i] << " ";
cout << endl;
return 0;
}
Output:
Sebelum: 64 34 25 12 22
Sesudah (Descending): 64 34 25 22 12
Perubahan yang dilakukan:
arr[j] > arr[j + 1] menjadi arr[j] < arr[j + 1]Soal: Berapa jumlah perbandingan minimum dan maksimum untuk Bubble Sort dengan optimasi pada array berukuran n=10?
Penyelesaian:
Minimum (Best Case):
Maksimum (Worst Case):
Formula umum:
Definisi: Selection Sort adalah algoritma sorting yang bekerja dengan memilih elemen minimum (atau maksimum) dari bagian yang belum terurut dan menukarnya dengan elemen di posisi yang sesuai.
Selection Sort membagi array menjadi dua bagian:
Langkah-langkah:

Gambar 9.3: Visualisasi proses Selection Sort pada array [64, 25, 12, 22, 11]
#include <iostream>
using namespace std;
void selectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
// Asumsikan elemen pertama dari bagian unsorted adalah minimum
int minIndex = i;
// Cari elemen minimum di bagian unsorted
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Tukar minimum dengan elemen pertama bagian unsorted
if (minIndex != i) {
swap(arr[i], arr[minIndex]);
}
}
}
int main() {
int arr[] = {64, 25, 12, 22, 11};
int n = 5;
cout << "Array sebelum sorting: ";
for (int i = 0; i < n; i++) cout << arr[i] << " ";
cout << endl;
selectionSort(arr, n);
cout << "Array setelah sorting: ";
for (int i = 0; i < n; i++) cout << arr[i] << " ";
cout << endl;
return 0;
}
Output:
Array sebelum sorting: 64 25 12 22 11
Array setelah sorting: 11 12 22 25 64
| Kasus | Kompleksitas Waktu | Penjelasan |
|---|---|---|
| Best Case | O(n²) | Tetap harus mencari minimum |
| Average Case | O(n²) | Sama untuk semua kasus |
| Worst Case | O(n²) | Sama untuk semua kasus |
Kompleksitas Ruang: O(1) — In-place algorithm
Karakteristik penting:
Soal: Trace eksekusi Selection Sort pada array [29, 10, 14, 37, 13]!
Penyelesaian:
Array awal: [29, 10, 14, 37, 13]
Iterasi 1 (i=0):
Iterasi 2 (i=1):
Iterasi 3 (i=2):
Iterasi 4 (i=3):
Array terurut: [10, 13, 14, 29, 37]
Statistik:
Soal: Mengapa Selection Sort melakukan jumlah swap yang lebih sedikit dibandingkan Bubble Sort?
Penyelesaian:
Perbandingan jumlah swap:
| Algoritma | Swap per Iterasi | Total Swap (Worst Case) |
|---|---|---|
| Bubble Sort | Bisa banyak (setiap pasangan tidak terurut) | O(n²) |
| Selection Sort | Maksimal 1 per iterasi | O(n) |
Alasan:
Selection Sort hanya melakukan satu swap per iterasi outer loop. Setelah menemukan minimum, langsung ditukar ke posisi final.
Bubble Sort melakukan swap setiap kali menemukan pasangan yang tidak terurut, yang bisa terjadi banyak kali dalam satu pass.
Contoh dengan array [5, 4, 3, 2, 1]:
Implikasi praktis:
Soal: Implementasikan Selection Sort untuk mengurutkan array of struct berdasarkan field tertentu!
Penyelesaian:
#include <iostream>
#include <cstring>
using namespace std;
struct Personel {
int id;
char nama[50];
int pangkat; // 1=Prajurit, 2=Kopral, 3=Sersan, dst
};
void selectionSortByPangkat(Personel arr[], int n) {
for (int i = 0; i < n - 1; i++) {
int maxIndex = i;
// Cari pangkat tertinggi (descending order)
for (int j = i + 1; j < n; j++) {
if (arr[j].pangkat > arr[maxIndex].pangkat) {
maxIndex = j;
}
}
if (maxIndex != i) {
swap(arr[i], arr[maxIndex]);
}
}
}
void cetakPersonel(Personel arr[], int n) {
cout << "ID\tNama\t\tPangkat" << endl;
cout << "--------------------------------" << endl;
for (int i = 0; i < n; i++) {
cout << arr[i].id << "\t" << arr[i].nama << "\t\t" << arr[i].pangkat << endl;
}
}
int main() {
Personel tim[] = {
{101, "Ahmad", 2},
{102, "Budi", 4},
{103, "Citra", 1},
{104, "Dewi", 3}
};
int n = 4;
cout << "Sebelum sorting:" << endl;
cetakPersonel(tim, n);
selectionSortByPangkat(tim, n);
cout << "\nSetelah sorting (by pangkat, descending):" << endl;
cetakPersonel(tim, n);
return 0;
}
Output:
Sebelum sorting:
ID Nama Pangkat
--------------------------------
101 Ahmad 2
102 Budi 4
103 Citra 1
104 Dewi 3
Setelah sorting (by pangkat, descending):
ID Nama Pangkat
--------------------------------
102 Budi 4
104 Dewi 3
101 Ahmad 2
103 Citra 1
Definisi: Insertion Sort adalah algoritma sorting yang membangun array terurut satu elemen pada satu waktu, dengan menyisipkan setiap elemen baru ke posisi yang tepat dalam bagian yang sudah terurut.
Insertion Sort bekerja seperti cara kita mengurutkan kartu di tangan:
Langkah-langkah:

Gambar 9.4: Visualisasi proses Insertion Sort pada array [12, 11, 13, 5, 6]
#include <iostream>
using namespace std;
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i]; // Elemen yang akan disisipkan
int j = i - 1;
// Geser elemen yang lebih besar dari key ke kanan
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
// Sisipkan key di posisi yang tepat
arr[j + 1] = key;
}
}
int main() {
int arr[] = {12, 11, 13, 5, 6};
int n = 5;
cout << "Array sebelum sorting: ";
for (int i = 0; i < n; i++) cout << arr[i] << " ";
cout << endl;
insertionSort(arr, n);
cout << "Array setelah sorting: ";
for (int i = 0; i < n; i++) cout << arr[i] << " ";
cout << endl;
return 0;
}
Output:
Array sebelum sorting: 12 11 13 5 6
Array setelah sorting: 5 6 11 12 13
| Kasus | Kompleksitas Waktu | Kondisi |
|---|---|---|
| Best Case | O(n) | Array sudah terurut |
| Average Case | O(n²) | Elemen tersebar acak |
| Worst Case | O(n²) | Array terurut terbalik |
Kompleksitas Ruang: O(1) — In-place algorithm
Soal: Trace eksekusi Insertion Sort pada array [7, 3, 5, 2]!
Penyelesaian:
Array awal: [7, 3, 5, 2]
Iterasi 1 (i=1):
Iterasi 2 (i=2):
Iterasi 3 (i=3):
Array terurut: [2, 3, 5, 7]
Soal: Mengapa Insertion Sort sangat efisien untuk data yang hampir terurut?
Penyelesaian:
Analisis Best Case (Array Terurut):
Untuk array [1, 2, 3, 4, 5]:
i=1: key=2, bandingkan dengan 1, 1<2, tidak geser, O(1)
i=2: key=3, bandingkan dengan 2, 2<3, tidak geser, O(1)
i=3: key=4, bandingkan dengan 3, 3<4, tidak geser, O(1)
i=4: key=5, bandingkan dengan 4, 4<5, tidak geser, O(1)
Total: n-1 perbandingan = O(n)
Analisis pada Data Hampir Terurut:
Untuk array [1, 2, 4, 3, 5] (hanya 3 dan 4 tertukar):
i=1: key=2, 1 perbandingan
i=2: key=4, 1 perbandingan
i=3: key=3, 2 perbandingan + 1 shift (hanya ini yang butuh kerja ekstra)
i=4: key=5, 1 perbandingan
Total: 5 perbandingan, mendekati O(n)
Kesimpulan:
while hanya berjalan jika ada elemen yang lebih besarIni berbeda dengan Selection Sort yang selalu O(n²) karena harus selalu mencari minimum di seluruh bagian unsorted.
Soal: Implementasikan Insertion Sort untuk mengurutkan linked list!
Penyelesaian:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
// Fungsi untuk menyisipkan node ke posisi yang tepat dalam list terurut
Node* sortedInsert(Node* sorted, Node* newNode) {
// Kasus khusus: list kosong atau node baru lebih kecil dari head
if (sorted == nullptr || sorted->data >= newNode->data) {
newNode->next = sorted;
return newNode;
}
// Cari posisi yang tepat
Node* current = sorted;
while (current->next != nullptr && current->next->data < newNode->data) {
current = current->next;
}
// Sisipkan node
newNode->next = current->next;
current->next = newNode;
return sorted;
}
Node* insertionSortLinkedList(Node* head) {
Node* sorted = nullptr;
Node* current = head;
while (current != nullptr) {
// Simpan next sebelum dimodifikasi
Node* next = current->next;
// Sisipkan current ke sorted list
sorted = sortedInsert(sorted, current);
// Lanjut ke node berikutnya
current = next;
}
return sorted;
}
// Fungsi helper untuk membuat node baru
Node* createNode(int data) {
Node* newNode = new Node();
newNode->data = data;
newNode->next = nullptr;
return newNode;
}
// Fungsi untuk mencetak linked list
void printList(Node* head) {
Node* temp = head;
while (temp != nullptr) {
cout << temp->data;
if (temp->next != nullptr) cout << " -> ";
temp = temp->next;
}
cout << " -> NULL" << endl;
}
int main() {
// Buat linked list: 12 -> 11 -> 13 -> 5 -> 6
Node* head = createNode(12);
head->next = createNode(11);
head->next->next = createNode(13);
head->next->next->next = createNode(5);
head->next->next->next->next = createNode(6);
cout << "Linked List sebelum sorting:" << endl;
printList(head);
head = insertionSortLinkedList(head);
cout << "Linked List setelah sorting:" << endl;
printList(head);
return 0;
}
Output:
Linked List sebelum sorting:
12 -> 11 -> 13 -> 5 -> 6 -> NULL
Linked List setelah sorting:
5 -> 6 -> 11 -> 12 -> 13 -> NULL
Penjelasan:
sorted yang awalnya kosongsortedSoal: Bandingkan jumlah operasi geser (shift) pada Insertion Sort untuk array yang terurut, terurut terbalik, dan acak dengan 5 elemen!
Penyelesaian:
Array terurut [1, 2, 3, 4, 5]:
i=1: key=2, 2>1, tidak geser
i=2: key=3, 3>2, tidak geser
i=3: key=4, 4>3, tidak geser
i=4: key=5, 5>4, tidak geser
Total shift: 0
Array terurut terbalik [5, 4, 3, 2, 1]:
i=1: key=4, 4<5, geser 5 → 1 shift
i=2: key=3, 3<5, 3<4, geser 5,4 → 2 shifts
i=3: key=2, 2<5, 2<4, 2<3, geser 5,4,3 → 3 shifts
i=4: key=1, 1<5, 1<4, 1<3, 1<2, geser 5,4,3,2 → 4 shifts
Total shift: 1+2+3+4 = 10
Array acak [3, 1, 4, 5, 2]:
i=1: key=1, 1<3, geser 3 → 1 shift
i=2: key=4, 4>3, tidak geser → 0 shifts
i=3: key=5, 5>4, tidak geser → 0 shifts
i=4: key=2, 2<5, 2<4, 2<3, geser 5,4,3 → 3 shifts
Total shift: 1+0+0+3 = 4
Ringkasan:
| Kondisi Array | Jumlah Shift |
|---|---|
| Terurut | 0 |
| Acak | 4 |
| Terurut Terbalik | 10 (maksimum) |
Jumlah shift maksimum = n(n-1)/2 = 5(4)/2 = 10
Definisi: Algoritma sorting dikatakan stable jika mempertahankan urutan relatif dari elemen-elemen yang memiliki nilai (key) yang sama.

Gambar 9.5: Perbandingan hasil stable sort dan unstable sort
Bayangkan database personel militer dengan data:
| Nama | Pangkat | Tahun Masuk |
|---|---|---|
| Ahmad | Sersan | 2020 |
| Budi | Kopral | 2019 |
| Citra | Sersan | 2018 |
| Dewi | Kopral | 2021 |
Jika sudah diurutkan berdasarkan tahun masuk, lalu diurutkan lagi berdasarkan pangkat:
Dengan Stable Sort:
Kopral: Budi (2019), Dewi (2021) -- urutan tahun dipertahankan
Sersan: Citra (2018), Ahmad (2020) -- urutan tahun dipertahankan
Dengan Unstable Sort:
Kopral: Dewi (2021), Budi (2019) -- urutan tahun BISA berubah
Sersan: Ahmad (2020), Citra (2018) -- urutan tahun BISA berubah
| Algoritma | Stabilitas | Alasan |
|---|---|---|
| Bubble Sort | Stable ✓ | Hanya menukar jika >, bukan >= |
| Selection Sort | Unstable ✗ | Swap jarak jauh dapat mengubah urutan |
| Insertion Sort | Stable ✓ | Hanya menggeser jika >, bukan >= |
Soal: Buktikan dengan contoh bahwa Selection Sort tidak stable!
Penyelesaian:
Array input dengan elemen bertanda:
Trace Selection Sort:
Iterasi 1 (i=0):
Iterasi 2 (i=1):
Iterasi 3 (i=2):
Hasil akhir: [2, 3, 5₁, 5₀]
Bukti ketidakstabilan:
Soal: Bagaimana membuat Selection Sort menjadi stable?
Penyelesaian:
Masalah utama: Swap jarak jauh dapat melewati elemen dengan nilai yang sama.
Solusi: Gunakan insert (seperti Insertion Sort) alih-alih swap.
void stableSelectionSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
// Cari indeks minimum
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Jika minimum bukan di posisi i
if (minIndex != i) {
// Simpan nilai minimum
int minVal = arr[minIndex];
// Geser semua elemen dari i sampai minIndex-1 ke kanan
// (seperti operasi insert pada Insertion Sort)
for (int k = minIndex; k > i; k--) {
arr[k] = arr[k - 1];
}
// Letakkan minimum di posisi i
arr[i] = minVal;
}
}
}
Trade-off:
Kesimpulan: Lebih baik gunakan Insertion Sort jika butuh stable sort dengan O(n²).
Soal: Implementasikan fungsi sorting untuk mengurutkan array personel berdasarkan pangkat (primary key) dan tahun masuk (secondary key) menggunakan stable sort!
Penyelesaian:
#include <iostream>
#include <cstring>
using namespace std;
struct Personel {
int id;
char nama[50];
int pangkat; // 1=Prajurit, 2=Kopral, 3=Sersan, 4=Serma
int tahunMasuk;
};
// Insertion Sort berdasarkan tahunMasuk (stable)
void sortByTahun(Personel arr[], int n) {
for (int i = 1; i < n; i++) {
Personel key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j].tahunMasuk > key.tahunMasuk) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
// Insertion Sort berdasarkan pangkat (stable)
void sortByPangkat(Personel arr[], int n) {
for (int i = 1; i < n; i++) {
Personel key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j].pangkat < key.pangkat) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
void cetakPersonel(Personel arr[], int n) {
cout << "ID\tNama\t\tPangkat\tTahun" << endl;
cout << "----------------------------------------" << endl;
for (int i = 0; i < n; i++) {
cout << arr[i].id << "\t" << arr[i].nama << "\t\t"
<< arr[i].pangkat << "\t" << arr[i].tahunMasuk << endl;
}
}
int main() {
Personel tim[] = {
{101, "Ahmad", 3, 2020},
{102, "Budi", 2, 2019},
{103, "Citra", 3, 2018},
{104, "Dewi", 2, 2021},
{105, "Eko", 4, 2017},
{106, "Fani", 3, 2019}
};
int n = 6;
cout << "Data Awal:" << endl;
cetakPersonel(tim, n);
// Langkah 1: Sort by secondary key (tahun masuk)
sortByTahun(tim, n);
cout << "\nSetelah sort by Tahun Masuk:" << endl;
cetakPersonel(tim, n);
// Langkah 2: Sort by primary key (pangkat) - stable sort
// Ini akan mempertahankan urutan tahun untuk pangkat yang sama
sortByPangkat(tim, n);
cout << "\nSetelah sort by Pangkat (mempertahankan urutan tahun):" << endl;
cetakPersonel(tim, n);
return 0;
}
Output:
Data Awal:
ID Nama Pangkat Tahun
----------------------------------------
101 Ahmad 3 2020
102 Budi 2 2019
103 Citra 3 2018
104 Dewi 2 2021
105 Eko 4 2017
106 Fani 3 2019
Setelah sort by Tahun Masuk:
ID Nama Pangkat Tahun
----------------------------------------
105 Eko 4 2017
103 Citra 3 2018
102 Budi 2 2019
106 Fani 3 2019
101 Ahmad 3 2020
104 Dewi 2 2021
Setelah sort by Pangkat (mempertahankan urutan tahun):
ID Nama Pangkat Tahun
----------------------------------------
105 Eko 4 2017
103 Citra 3 2018
106 Fani 3 2019
101 Ahmad 3 2020
102 Budi 2 2019
104 Dewi 2 2021
Verifikasi:
| Kriteria | Bubble Sort | Selection Sort | Insertion Sort |
|---|---|---|---|
| Best Case | O(n)* | O(n²) | O(n) |
| Average Case | O(n²) | O(n²) | O(n²) |
| Worst Case | O(n²) | O(n²) | O(n²) |
| Space | O(1) | O(1) | O(1) |
| Stable | ✓ Yes | ✗ No | ✓ Yes |
| Adaptive | ✓ Yes* | ✗ No | ✓ Yes |
| # Comparisons | n(n-1)/2 | n(n-1)/2 | n-1 to n(n-1)/2 |
| # Swaps | 0 to n(n-1)/2 | 0 to n-1 | 0 |
*dengan optimasi early termination

Gambar 9.6: Flowchart pemilihan algoritma sorting dasar
Rekomendasi penggunaan:
Soal: Untuk array dengan 1000 elemen yang hampir terurut (hanya 5 elemen tidak pada tempatnya), algoritma mana yang paling efisien? Jelaskan!
Penyelesaian:
Jawaban: Insertion Sort
Analisis:
| Algoritma | Performa pada Data Hampir Terurut |
|---|---|
| Bubble Sort | O(n) dengan optimasi, tapi banyak perbandingan tidak perlu |
| Selection Sort | Tetap O(n²), harus mencari minimum setiap iterasi |
| Insertion Sort | Mendekati O(n), hanya 5 elemen perlu digeser jauh |
Perhitungan untuk Insertion Sort:
Perhitungan untuk Selection Sort:
Kesimpulan: Insertion Sort sekitar 100× lebih cepat dari Selection Sort untuk kasus ini.
Soal: Implementasikan program yang membandingkan jumlah operasi ketiga algoritma sorting!
Penyelesaian:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
// Struktur untuk menyimpan statistik
struct SortStats {
long long comparisons;
long long swaps;
long long shifts;
};
// Bubble Sort dengan statistik
SortStats bubbleSortWithStats(int arr[], int n) {
SortStats stats = {0, 0, 0};
bool swapped;
for (int i = 0; i < n - 1; i++) {
swapped = false;
for (int j = 0; j < n - i - 1; j++) {
stats.comparisons++;
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
stats.swaps++;
swapped = true;
}
}
if (!swapped) break;
}
return stats;
}
// Selection Sort dengan statistik
SortStats selectionSortWithStats(int arr[], int n) {
SortStats stats = {0, 0, 0};
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
stats.comparisons++;
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
if (minIndex != i) {
swap(arr[i], arr[minIndex]);
stats.swaps++;
}
}
return stats;
}
// Insertion Sort dengan statistik
SortStats insertionSortWithStats(int arr[], int n) {
SortStats stats = {0, 0, 0};
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0) {
stats.comparisons++;
if (arr[j] > key) {
arr[j + 1] = arr[j];
stats.shifts++;
j--;
} else {
break;
}
}
arr[j + 1] = key;
}
return stats;
}
void generateRandomArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
arr[i] = rand() % 1000;
}
}
void generateSortedArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
arr[i] = i;
}
}
void generateReversedArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
arr[i] = n - i;
}
}
int main() {
srand(time(0));
const int N = 100;
int arr1[N], arr2[N], arr3[N];
cout << "=== PERBANDINGAN ALGORITMA SORTING (n=" << N << ") ===" << endl;
// Test 1: Random Array
generateRandomArray(arr1, N);
memcpy(arr2, arr1, sizeof(arr1));
memcpy(arr3, arr1, sizeof(arr1));
cout << "\n1. Array Random:" << endl;
SortStats bs = bubbleSortWithStats(arr1, N);
SortStats ss = selectionSortWithStats(arr2, N);
SortStats is = insertionSortWithStats(arr3, N);
cout << " Bubble Sort - Comparisons: " << bs.comparisons
<< ", Swaps: " << bs.swaps << endl;
cout << " Selection Sort - Comparisons: " << ss.comparisons
<< ", Swaps: " << ss.swaps << endl;
cout << " Insertion Sort - Comparisons: " << is.comparisons
<< ", Shifts: " << is.shifts << endl;
// Test 2: Already Sorted Array
generateSortedArray(arr1, N);
memcpy(arr2, arr1, sizeof(arr1));
memcpy(arr3, arr1, sizeof(arr1));
cout << "\n2. Array Terurut:" << endl;
bs = bubbleSortWithStats(arr1, N);
ss = selectionSortWithStats(arr2, N);
is = insertionSortWithStats(arr3, N);
cout << " Bubble Sort - Comparisons: " << bs.comparisons
<< ", Swaps: " << bs.swaps << endl;
cout << " Selection Sort - Comparisons: " << ss.comparisons
<< ", Swaps: " << ss.swaps << endl;
cout << " Insertion Sort - Comparisons: " << is.comparisons
<< ", Shifts: " << is.shifts << endl;
// Test 3: Reversed Array
generateReversedArray(arr1, N);
memcpy(arr2, arr1, sizeof(arr1));
memcpy(arr3, arr1, sizeof(arr1));
cout << "\n3. Array Terbalik:" << endl;
bs = bubbleSortWithStats(arr1, N);
ss = selectionSortWithStats(arr2, N);
is = insertionSortWithStats(arr3, N);
cout << " Bubble Sort - Comparisons: " << bs.comparisons
<< ", Swaps: " << bs.swaps << endl;
cout << " Selection Sort - Comparisons: " << ss.comparisons
<< ", Swaps: " << ss.swaps << endl;
cout << " Insertion Sort - Comparisons: " << is.comparisons
<< ", Shifts: " << is.shifts << endl;
return 0;
}
Contoh Output:
=== PERBANDINGAN ALGORITMA SORTING (n=100) ===
1. Array Random:
Bubble Sort - Comparisons: 4950, Swaps: 2387
Selection Sort - Comparisons: 4950, Swaps: 99
Insertion Sort - Comparisons: 2486, Shifts: 2387
2. Array Terurut:
Bubble Sort - Comparisons: 99, Swaps: 0
Selection Sort - Comparisons: 4950, Swaps: 0
Insertion Sort - Comparisons: 99, Shifts: 0
3. Array Terbalik:
Bubble Sort - Comparisons: 4950, Swaps: 4950
Selection Sort - Comparisons: 4950, Swaps: 50
Insertion Sort - Comparisons: 4950, Shifts: 4950
Soal: Dalam sistem radar pertahanan, objek terdeteksi diurutkan berdasarkan jarak untuk prioritas tracking. Data update setiap 0.1 detik dengan perubahan minimal. Algoritma sorting mana yang paling cocok dan mengapa? Implementasikan!
Penyelesaian:
Analisis:
Jawaban: Insertion Sort adalah pilihan terbaik karena:
Implementasi:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
struct ObjekRadar {
int id;
double jarak; // km dari radar
double azimuth; // derajat (0-360)
double kecepatan; // km/jam
char jenis[20];
int threatLevel; // 1-5
};
// Insertion Sort berdasarkan jarak (ascending)
// Dioptimasi untuk data hampir terurut
void sortByJarak(ObjekRadar arr[], int n) {
for (int i = 1; i < n; i++) {
ObjekRadar key = arr[i];
int j = i - 1;
// Hanya geser jika benar-benar perlu
while (j >= 0 && arr[j].jarak > key.jarak) {
arr[j + 1] = arr[j];
j--;
}
// Hanya assignment jika ada pergerakan
if (j + 1 != i) {
arr[j + 1] = key;
}
}
}
// Simulasi update posisi (objek bergerak sedikit)
void updatePosisi(ObjekRadar arr[], int n) {
for (int i = 0; i < n; i++) {
// Random movement: -2 to +2 km (kecil)
double delta = (rand() % 500 - 250) / 100.0;
arr[i].jarak += delta;
if (arr[i].jarak < 0) arr[i].jarak = 0;
}
}
void cetakRadar(ObjekRadar arr[], int n) {
cout << "ID\tJarak(km)\tAzimuth\tThreat" << endl;
cout << "----------------------------------------" << endl;
for (int i = 0; i < n; i++) {
cout << arr[i].id << "\t"
<< fixed << arr[i].jarak << "\t\t"
<< arr[i].azimuth << "\t"
<< arr[i].threatLevel << endl;
}
}
int main() {
srand(42); // Seed untuk reproducibility
// Inisialisasi objek radar
ObjekRadar radar[] = {
{1001, 50.5, 45, 200, "Pesawat", 2},
{1002, 75.2, 120, 150, "Helikopter", 1},
{1003, 120.8, 200, 400, "Jet", 3},
{1004, 35.1, 90, 100, "Drone", 4},
{1005, 200.0, 270, 500, "Rudal", 5}
};
int n = 5;
cout << "=== SISTEM TRACKING RADAR ===" << endl;
// Initial sort
sortByJarak(radar, n);
cout << "\nPosisi Awal (sorted by jarak):" << endl;
cetakRadar(radar, n);
// Simulasi 3 cycle update
for (int cycle = 1; cycle <= 3; cycle++) {
cout << "\n--- Update Cycle " << cycle << " ---" << endl;
// Update posisi (perubahan kecil)
updatePosisi(radar, n);
// Re-sort (sangat cepat karena hampir terurut)
sortByJarak(radar, n);
cetakRadar(radar, n);
}
return 0;
}
Output:
=== SISTEM TRACKING RADAR ===
Posisi Awal (sorted by jarak):
ID Jarak(km) Azimuth Threat
----------------------------------------
1004 35.100000 90 4
1001 50.500000 45 2
1002 75.200000 120 1
1003 120.800000 200 3
1005 200.000000 270 5
--- Update Cycle 1 ---
ID Jarak(km) Azimuth Threat
----------------------------------------
1004 35.380000 90 4
1001 49.730000 45 2
1002 73.380000 120 1
1003 122.290000 200 3
1005 199.510000 270 5
--- Update Cycle 2 ---
...
Keuntungan pendekatan ini:
Soal: Implementasikan generic sorting function menggunakan function pointer agar dapat mengurutkan berbagai tipe data!
Penyelesaian:
#include <iostream>
#include <cstring>
using namespace std;
// Tipe function pointer untuk fungsi perbandingan
// Return: negative jika a < b, 0 jika a == b, positive jika a > b
typedef int (*CompareFunc)(const void*, const void*);
// Generic Insertion Sort
void genericInsertionSort(void* arr, int n, int size, CompareFunc compare) {
char* base = (char*)arr;
char* temp = new char[size]; // Temporary storage
for (int i = 1; i < n; i++) {
// Copy current element to temp
memcpy(temp, base + i * size, size);
int j = i - 1;
while (j >= 0 && compare(base + j * size, temp) > 0) {
// Shift element to the right
memcpy(base + (j + 1) * size, base + j * size, size);
j--;
}
// Insert temp at correct position
memcpy(base + (j + 1) * size, temp, size);
}
delete[] temp;
}
// === Fungsi Perbandingan untuk Integer ===
int compareIntAsc(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int compareIntDesc(const void* a, const void* b) {
return (*(int*)b - *(int*)a);
}
// === Fungsi Perbandingan untuk String ===
int compareStrAsc(const void* a, const void* b) {
return strcmp((char*)a, (char*)b);
}
// === Struct dan fungsi perbandingannya ===
struct Mahasiswa {
int nim;
char nama[50];
double ipk;
};
int compareMhsByNIM(const void* a, const void* b) {
return ((Mahasiswa*)a)->nim - ((Mahasiswa*)b)->nim;
}
int compareMhsByIPK(const void* a, const void* b) {
double diff = ((Mahasiswa*)b)->ipk - ((Mahasiswa*)a)->ipk;
if (diff > 0) return 1;
if (diff < 0) return -1;
return 0;
}
int main() {
// Test 1: Sort integer array (ascending)
cout << "=== Test 1: Integer Ascending ===" << endl;
int nums[] = {64, 34, 25, 12, 22, 11, 90};
int n = 7;
cout << "Before: ";
for (int i = 0; i < n; i++) cout << nums[i] << " ";
cout << endl;
genericInsertionSort(nums, n, sizeof(int), compareIntAsc);
cout << "After: ";
for (int i = 0; i < n; i++) cout << nums[i] << " ";
cout << endl;
// Test 2: Sort integer array (descending)
cout << "\n=== Test 2: Integer Descending ===" << endl;
int nums2[] = {64, 34, 25, 12, 22, 11, 90};
genericInsertionSort(nums2, n, sizeof(int), compareIntDesc);
cout << "Result: ";
for (int i = 0; i < n; i++) cout << nums2[i] << " ";
cout << endl;
// Test 3: Sort struct by different fields
cout << "\n=== Test 3: Struct Mahasiswa ===" << endl;
Mahasiswa mhs[] = {
{103, "Citra", 3.75},
{101, "Ahmad", 3.50},
{104, "Dewi", 3.90},
{102, "Budi", 3.25}
};
int m = 4;
cout << "By NIM:" << endl;
genericInsertionSort(mhs, m, sizeof(Mahasiswa), compareMhsByNIM);
for (int i = 0; i < m; i++) {
cout << mhs[i].nim << " - " << mhs[i].nama
<< " (IPK: " << mhs[i].ipk << ")" << endl;
}
cout << "\nBy IPK (descending):" << endl;
genericInsertionSort(mhs, m, sizeof(Mahasiswa), compareMhsByIPK);
for (int i = 0; i < m; i++) {
cout << mhs[i].nim << " - " << mhs[i].nama
<< " (IPK: " << mhs[i].ipk << ")" << endl;
}
return 0;
}
Output:
=== Test 1: Integer Ascending ===
Before: 64 34 25 12 22 11 90
After: 11 12 22 25 34 64 90
=== Test 2: Integer Descending ===
Result: 90 64 34 25 22 12 11
=== Test 3: Struct Mahasiswa ===
By NIM:
101 - Ahmad (IPK: 3.5)
102 - Budi (IPK: 3.25)
103 - Citra (IPK: 3.75)
104 - Dewi (IPK: 3.9)
By IPK (descending):
104 - Dewi (IPK: 3.9)
103 - Citra (IPK: 3.75)
101 - Ahmad (IPK: 3.5)
102 - Budi (IPK: 3.25)
Soal: Implementasikan Binary Insertion Sort yang menggunakan binary search untuk menemukan posisi insert!
Penyelesaian:
#include <iostream>
using namespace std;
// Binary search untuk menemukan posisi insert
int binarySearch(int arr[], int item, int low, int high) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (item == arr[mid])
return mid + 1; // Insert setelah elemen yang sama (stable)
if (item > arr[mid])
low = mid + 1;
else
high = mid - 1;
}
return low; // Posisi insert
}
void binaryInsertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
// Gunakan binary search untuk mencari posisi insert
// Hanya di bagian yang sudah terurut [0..i-1]
int pos = binarySearch(arr, key, 0, j);
// Geser semua elemen dari pos sampai i-1 ke kanan
while (j >= pos) {
arr[j + 1] = arr[j];
j--;
}
// Insert key di posisi yang tepat
arr[pos] = key;
}
}
// Standard Insertion Sort untuk perbandingan
void standardInsertionSort(int arr[], int n, int& comparisons) {
comparisons = 0;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0) {
comparisons++;
if (arr[j] > key) {
arr[j + 1] = arr[j];
j--;
} else {
break;
}
}
arr[j + 1] = key;
}
}
// Binary Insertion Sort dengan counting
void binaryInsertionSortWithCount(int arr[], int n, int& comparisons) {
comparisons = 0;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
int low = 0, high = j;
// Binary search dengan counting
while (low <= high) {
comparisons++;
int mid = low + (high - low) / 2;
if (key >= arr[mid])
low = mid + 1;
else
high = mid - 1;
}
int pos = low;
while (j >= pos) {
arr[j + 1] = arr[j];
j--;
}
arr[pos] = key;
}
}
int main() {
const int N = 20;
int arr1[N], arr2[N];
// Generate random array
srand(42);
for (int i = 0; i < N; i++) {
arr1[i] = rand() % 100;
arr2[i] = arr1[i];
}
cout << "Array awal: ";
for (int i = 0; i < N; i++) cout << arr1[i] << " ";
cout << endl;
int comp1, comp2;
standardInsertionSort(arr1, N, comp1);
binaryInsertionSortWithCount(arr2, N, comp2);
cout << "\nHasil Standard Insertion Sort: ";
for (int i = 0; i < N; i++) cout << arr1[i] << " ";
cout << endl;
cout << "Jumlah perbandingan: " << comp1 << endl;
cout << "\nHasil Binary Insertion Sort: ";
for (int i = 0; i < N; i++) cout << arr2[i] << " ";
cout << endl;
cout << "Jumlah perbandingan: " << comp2 << endl;
cout << "\n=== ANALISIS ===" << endl;
cout << "Standard: O(n^2) comparisons dalam worst case" << endl;
cout << "Binary: O(n log n) comparisons" << endl;
cout << "Catatan: Keduanya tetap O(n^2) karena shift masih O(n) per elemen" << endl;
return 0;
}
Output:
Array awal: 67 93 49 38 74 36 15 44 22 71 63 52 13 59 41 88 50 29 96 24
Hasil Standard Insertion Sort: 13 15 22 24 29 36 38 41 44 49 50 52 59 63 67 71 74 88 93 96
Jumlah perbandingan: 107
Hasil Binary Insertion Sort: 13 15 22 24 29 36 38 41 44 49 50 52 59 63 67 71 74 88 93 96
Jumlah perbandingan: 66
=== ANALISIS ===
Standard: O(n^2) comparisons dalam worst case
Binary: O(n log n) comparisons
Catatan: Keduanya tetap O(n^2) karena shift masih O(n) per elemen
Analisis:
Soal: Sistem komunikasi militer menerima pesan dengan timestamp dan priority. Implementasikan sorting yang mengurutkan berdasarkan priority (primary) dan timestamp (secondary) dengan efisien!
Penyelesaian:
#include <iostream>
#include <cstring>
#include <ctime>
using namespace std;
struct MilitaryMessage {
int id;
int priority; // 1=LOW, 2=NORMAL, 3=HIGH, 4=URGENT, 5=FLASH
long timestamp; // Unix timestamp
char sender[50];
char content[200];
bool encrypted;
};
// Comparator: Sort by priority DESC, then timestamp ASC
bool shouldSwap(const MilitaryMessage& a, const MilitaryMessage& b) {
// Primary key: priority (descending - higher priority first)
if (a.priority != b.priority) {
return a.priority < b.priority; // Swap jika a priority lebih rendah
}
// Secondary key: timestamp (ascending - older messages first within same priority)
return a.timestamp > b.timestamp; // Swap jika a lebih baru
}
// Insertion Sort - stable dan adaptif
void sortMessages(MilitaryMessage arr[], int n) {
for (int i = 1; i < n; i++) {
MilitaryMessage key = arr[i];
int j = i - 1;
while (j >= 0 && shouldSwap(arr[j], key)) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
const char* getPriorityName(int p) {
switch(p) {
case 1: return "LOW";
case 2: return "NORMAL";
case 3: return "HIGH";
case 4: return "URGENT";
case 5: return "FLASH";
default: return "UNKNOWN";
}
}
void printMessages(MilitaryMessage arr[], int n) {
cout << "ID\tPriority\tTimestamp\tSender\t\tEncrypted" << endl;
cout << "================================================================" << endl;
for (int i = 0; i < n; i++) {
cout << arr[i].id << "\t"
<< getPriorityName(arr[i].priority) << "\t\t"
<< arr[i].timestamp << "\t"
<< arr[i].sender << "\t\t"
<< (arr[i].encrypted ? "Yes" : "No") << endl;
}
}
int main() {
// Simulasi message queue
MilitaryMessage messages[] = {
{1001, 2, 1700000100, "Alpha-1", "Status report", true},
{1002, 4, 1700000050, "Bravo-2", "Enemy spotted", true},
{1003, 3, 1700000200, "Charlie-3", "Request backup", false},
{1004, 5, 1700000150, "HQ", "FLASH message", true},
{1005, 4, 1700000080, "Delta-4", "Position update", true},
{1006, 2, 1700000020, "Echo-5", "Routine check", false},
{1007, 5, 1700000120, "HQ", "Priority intel", true},
{1008, 3, 1700000180, "Alpha-1", "Mission complete", true}
};
int n = 8;
cout << "=== MILITARY MESSAGE QUEUE ===" << endl;
cout << "\nBefore Sorting (arrival order):" << endl;
printMessages(messages, n);
sortMessages(messages, n);
cout << "\nAfter Sorting (by Priority DESC, Timestamp ASC):" << endl;
printMessages(messages, n);
cout << "\n=== PROCESSING ORDER ===" << endl;
cout << "Messages will be processed in this order:" << endl;
for (int i = 0; i < n; i++) {
cout << (i+1) << ". [" << getPriorityName(messages[i].priority)
<< "] " << messages[i].sender << ": " << messages[i].content << endl;
}
return 0;
}
Output:
=== MILITARY MESSAGE QUEUE ===
Before Sorting (arrival order):
ID Priority Timestamp Sender Encrypted
================================================================
1001 NORMAL 1700000100 Alpha-1 Yes
1002 URGENT 1700000050 Bravo-2 Yes
1003 HIGH 1700000200 Charlie-3 No
1004 FLASH 1700000150 HQ Yes
1005 URGENT 1700000080 Delta-4 Yes
1006 NORMAL 1700000020 Echo-5 No
1007 FLASH 1700000120 HQ Yes
1008 HIGH 1700000180 Alpha-1 Yes
After Sorting (by Priority DESC, Timestamp ASC):
ID Priority Timestamp Sender Encrypted
================================================================
1007 FLASH 1700000120 HQ Yes
1004 FLASH 1700000150 HQ Yes
1002 URGENT 1700000050 Bravo-2 Yes
1005 URGENT 1700000080 Delta-4 Yes
1008 HIGH 1700000180 Alpha-1 Yes
1003 HIGH 1700000200 Charlie-3 No
1006 NORMAL 1700000020 Echo-5 No
1001 NORMAL 1700000100 Alpha-1 Yes
=== PROCESSING ORDER ===
Messages will be processed in this order:
1. [FLASH] HQ: Priority intel
2. [FLASH] HQ: FLASH message
3. [URGENT] Bravo-2: Enemy spotted
4. [URGENT] Delta-4: Position update
5. [HIGH] Alpha-1: Mission complete
6. [HIGH] Charlie-3: Request backup
7. [NORMAL] Echo-5: Routine check
8. [NORMAL] Alpha-1: Status report
Kerjakan soal-soal berikut untuk latihan tambahan. Jawaban singkat tersedia di bagian akhir.
Apa output Bubble Sort optimized pada array [1, 2, 3, 5, 4]? Berapa jumlah pass yang dilakukan?
Implementasikan Cocktail Shaker Sort (variasi Bubble Sort yang maju-mundur)!
Untuk n=1000, berapa perbandingan yang dilakukan Selection Sort? Apakah berbeda untuk best, average, dan worst case?
Modifikasi Insertion Sort agar dapat menangani data yang masuk secara streaming (satu per satu) dengan efisien!
Buktikan secara matematis bahwa lower bound untuk comparison-based sorting adalah Ω(n log n)!
| Konsep | Deskripsi | Catatan Penting |
|---|---|---|
| Sorting | Proses menyusun ulang elemen berdasarkan kriteria | Fundamental dalam ilmu komputer |
| Bubble Sort | Menukar elemen bersebelahan yang tidak terurut | O(n) best case dengan optimasi |
| Selection Sort | Memilih minimum dan swap ke posisi yang tepat | Jumlah swap minimum: O(n) |
| Insertion Sort | Menyisipkan elemen ke posisi yang tepat | Terbaik untuk data hampir terurut |
| Stable Sort | Mempertahankan urutan relatif elemen dengan nilai sama | Bubble & Insertion stable |
| Adaptive Sort | Performa lebih baik pada data hampir terurut | Bubble (optimized) & Insertion |
| In-place Sort | Membutuhkan O(1) memori tambahan | Ketiga algoritma in-place |
| Kompleksitas | Ketiga algoritma O(n²) average/worst case | Tidak cocok untuk data besar |
S1:
S2:
void cocktailShakerSort(int arr[], int n) {
bool swapped = true;
int start = 0, end = n - 1;
while (swapped) {
swapped = false;
// Left to right pass
for (int i = start; i < end; i++) {
if (arr[i] > arr[i + 1]) {
swap(arr[i], arr[i + 1]);
swapped = true;
}
}
if (!swapped) break;
end--;
swapped = false;
// Right to left pass
for (int i = end - 1; i >= start; i--) {
if (arr[i] > arr[i + 1]) {
swap(arr[i], arr[i + 1]);
swapped = true;
}
}
start++;
}
}
S3:
S4:
// Maintain sorted array, insert new element
void insertSorted(int arr[], int& n, int newVal) {
int i = n - 1;
while (i >= 0 && arr[i] > newVal) {
arr[i + 1] = arr[i];
i--;
}
arr[i + 1] = newVal;
n++;
}
S5:
This repository is licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0). Commercial use is permitted, provided attribution is given to the author.
© 2026 Anindito