MAKALAH PROYEK AKHIR ALGORITMA PEMROGRAMAN KELOMPOK 03 Dosen Pengampu: Dian Rachmawati S.Si, M.kom. Disusun Oleh: 1. Anantha Aulia Rahman Nasution (231401072) 2. Annisa Putri Aprilia (231401036) 3. Marco Aprilian Leonard (231401069) 4. Vuitton Varian Utomo (231401063) 5. Sulung Ismanara (231401060) UNIVERSITAS SUMATERA UTARA MEDAN 2024 BAB I PEMBAHASAN 1.1 Hanoi Tower Menara Hanoi (Hanoi Tower) adalah sebuah permainan teka-teki yang bertujuan untuk menyusun tumpukan cakram dari yang terbesar (bawah) ke yang terkecil (atas). Menara Hanoi diciptakan oleh Édouard Lucas, ahli matematika Prancis pada tahun 1883. Permainan ini terdiri dari tiga tiang dan sejumlah cakram dengan ukuran berbeda-beda yang bisa dimasukkan ke tiang mana saja. Permainan dimulai dengan cakram-cakram yang tertumpuk rapi berurutan berdasarkan ukurannya dalam salah satu tiang, cakram terkecil diletakkan teratas, sehingga membentuk kerucut. Permainan ini memiliki 3 aturan utama : 1. Hanya satu cakram yang boleh dipindahkan dalam satu waktu. 2. Setiap perpindahan berupa pengambilan cakram teratas dari satu tiang dan memasukkannya ke tiang lain, di atas cakram lain yang mungkin sudah ada di tiang tersebut. 3. Tidak boleh meletakkan cakram di atas cakram yang lebih kecil. Menara Hanoi dapat dimainkan dengan berbagai jumlah cakram, walaupun biasanya banyak versi mainan menggunakan 7-9 cakram. Jumlah gerakan paling efisien yang dibutuhkan untuk menyelesaikan Menara Hanoi adalah 2n – 1 gerakan, dimana n merupakan jumlah cakram yang digunakan. Solusi sederhana untuk menyelesaikan permainan ini adalah dengan memindahkan cakram terkecil dan cakram terbesar secara selang seling. Saat memindahkan cakram terkecil, selalu pindahkan ke arah yang sama. Jika tidak ada posisi menara ke arah yang ditentukan, pindahkan cakram ke arah yg berlawanan. Permainan menara hanoi sudah diterapkan diberbagai bidang selama bertahun-tahun, seperti dalam tes pemecahan masalah pada tes psikologi, menara hanoi juga digunakan oleh dokter ahli saraf untuk evaluasi lobus frontal. Menara Hanoi merupakan alat ajar yang sering digunakan pada pelajaran recursive algorithm dalam komputasi. Berbagai media hiburan juga banyak menggunakan menara hanoi sebagai referensi. • Contoh Program #include <iostream> #include <vector> #include <stack> 2 #include <cmath> using namespace std; char menara[3]={'A', 'B', 'C'}; vector<stack<int>> tumpuk(3); void pindah(int a, int b) { if (tumpuk[b].empty() || (!tumpuk[a].empty() && tumpuk[a].top() < tumpuk[b].top())) { cout << "Cakram " << tumpuk[a].top() << " pindah dari menara " << menara[a] << " ke menara " << menara[b] << "\n"; tumpuk[b].push(tumpuk[a].top()); tumpuk[a].pop(); } else pindah(b, a); } void menarahanoi(int n) { int total = 0; cout << "Jumlah Cakram = " << n <<endl; int awal = 0, bantu = 1, tujuan = 2; for (int i = n; i > 0; i--) tumpuk[awal].push(i); int jumlahgerak = (pow(2,n)) - 1; if (n % 2 == 0) swap(bantu, tujuan); for (int i = 1; i <= jumlahgerak; i++) { if (i % 3 == 0) pindah(bantu, tujuan); else if (i % 3 == 1) pindah(awal, tujuan); else pindah(awal, bantu); 3 total += 1; } printf("Jumlah gerakan yang diperlukan = %d", total); } int main() { system("CLS"); int n; printf("Masukkan jumlah cakram yang akan digunakan : "); scanf("%d", &n); menarahanoi(n); } Output: 1.2 Sorting Sorting (Pengurutan) adalah suatu proses penyusunan kembali kumpulan objek menggunakan tata aturan tertentu. Sorting disebut juga sebagai suatu algoritma untuk meletakkan kumpulan elemen data ke dalam urutan tertentu berdasarkan satu atau beberapa kunci dalam tiap-tiap elemen. Pengurutan atau sorting merupakan proses dasar yang ada dalam sebuah algoritma dan struktur data. Tujuan utama dari proses pengurutan atau sorting adalah untuk mengurutkan data berdasarkan keinginan baik itu dari yang terendah maupun yang tertinggi, sehingga data yang dihasilkan akan lebih terstruktur, teratur dan sesuai dengan kebutuhan. 4 Beberapa contoh algoritma sorting yang akan dibahas sebagai berikut: A. Heap Sort 1. Heap sort adalah teknik pengurutan berbasis perbandingan berdasarkan struktur data Binary Heap. Ini mirip dengan pengurutan seleksi di mana kita pertama kali menemukan elemen minimum dan menempatkan elemen minimum di awal. Ulangi proses yang sama untuk elemen lainnya. Algoritma Heap sort: contoh Perhatikan arraynya: arr[] = {4, 10, 3, 5, 1}. 2. Transformasi menjadi max heap: Setelah itu, tugasnya adalah membuat pohon dari array yang tidak disortir dan mencoba mengubahnya menjadi max heap. Untuk mengubah heap menjadi max-heap, node induk harus selalu lebih besar atau sama dengan node anak. Di sini, dalam contoh ini, karena node induk 4 lebih kecil dari node anak 10, maka tukar node tersebut untuk membangun max-heap. Sekarang, 4 sebagai induk lebih kecil dari anak 5 , maka tukar keduanya lagi dan heap dan array yang dihasilkan akan menjadi seperti ini: 5 3. Lakukan pengurutan heap: Hapus elemen maksimum di setiap langkah (yaitu, pindahkan ke posisi akhir dan hapus elemen tersebut) lalu pertimbangkan elemen yang tersisa dan ubah menjadi heap maksimal. Hapus elemen root (10) dari tumpukan maksimal. Untuk menghapus node ini, cobalah menukarnya dengan node terakhir, yaitu (1). Setelah menghapus elemen root, tumpukan lagi untuk mengubahnya menjadi tumpukan maksimal. Heap dan array yang dihasilkan akan terlihat seperti ini: Kemudian ulangi langkah hingga semua sudah terurut. • Kelebihan: 6 1 2 • Efisiensi Waktu: Heap Sort memiliki waktu eksekusi yang konsisten O(n log n) untuk kasus terbaik, rata-rata, dan terburuk. Tidak Membutuhkan Memori Tambahan: Heap Sort adalah algoritma in-place, artinya tidak memerlukan memori tambahan yang signifikan. Kekurangan: 1. Kurang Efisien Dibandingkan Quick Sort: Untuk banyak aplikasi praktis, Quick Sort sering kali lebih cepat daripada Heap Sort karena konstanta tersembunyi dalam kompleksitas waktu. 2. Akses Memori Acak: Heap Sort memerlukan akses memori acak yang mungkin kurang efisien pada beberapa jenis memori atau arsitektur. • Contoh Program #include <iostream> #include <vector> using namespace std; void heap(vector<int>& arr, int n, int i) { int largest = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left < n && arr[left] > arr[largest]) largest = left; 7 if (right < n && arr[right] > arr[largest]) largest = right; if (largest != i) { swap(arr[i], arr[largest]); //rekursif heap(arr, n, largest); } } void heapSort(vector<int>& arr) { int n = arr.size(); for (int i = n / 2 - 1; i >= 0; i--) heap(arr, n, i); for (int i = n - 1; i >= 0; i--) { swap(arr[0], arr[i]); 8 heap(arr, i, 0); } } void printArray(const vector<int>& arr) { for (int i = 0; i < arr.size(); i++) cout << arr[i] << " "; cout << endl; } int main() { system("CLS"); int n; printf("Masukkan size dari deret bilangan: "); scanf("%d", &n); vector <int> arr(n); for (int i = 0; i < n; i++) 9 { cin >> arr[i]; } printf("Array awal: "); printArray(arr); heapSort(arr); printf("Array yang telah diurutkan: "); printArray(arr); return 0; } Ouput: B. 3-way Merge sort Merge sort melibatkan pemisahan array menjadi 2 bagian secara rekursif, mengurutkan, dan akhirnya menggabungkannya. Varian dari Merge sort disebut 3way merge sort yang mana alih-alih membagi array menjadi 2 bagian, kita membaginya menjadi 3 bagian. 10 Algoritma 3 way merge sort 1. Pembagian: Array yang akan di-sort dibagi menjadi tiga bagian yang kira-kira sama besar. 2. Rekursif: Setiap bagian di-sort secara rekursif menggunakan Three-Way Merge Sort. 3. Penggabungan: Tiga bagian yang telah di-sort digabungkan kembali menjadi satu array yang telah di-sort. • • Kelebihan: 1 Kinerja yang lebih baik dalam beberapa kasus: Dalam kasus tertentu, 3-way merge sort dapat memiliki kinerja yang lebih baik daripada merge sort 2-way karena mengurangi jumlah perbandingan yang diperlukan untuk menggabungkan bagian-bagian yang sudah terurut. 2 Mengurangi kedalaman rekursi: Dibandingkan dengan merge sort 2-way, 3-way merge sort dapat mengurangi kedalaman rekursi, yang dapat mengurangi beban pada stack rekursi dan meminimalkan risiko terjadinya stack overflow pada input yang sangat besar. Kekurangan: 1. Implementasi yang lebih kompleks: 3-way merge sort membutuhkan implementasi yang lebih kompleks daripada merge sort 2-way karena harus mengelola tiga bagian yang berbeda saat penggabungan. 11 2. Performa yang lebih buruk pada kasus terbaik: Meskipun 3-way merge sort dapat memiliki kinerja yang lebih baik dalam beberapa kasus, dalam kasus terbaik di mana input sudah terurut atau hampir terurut, 3-way merge sort mungkin tidak seefisien merge sort 2-way karena overhead yang terkait dengan pengelolaan tiga bagian. Ditambah fakta bahwa kompleksitas waktu yang sama dengan merge sort biasa yaitu O(n log n) sehingga kompleksitasnya tetap sama. • Contoh Program : #include <iostream> #include <vector> #include <algorithm> using namespace std; void merge(vector<int>& arr, int left, int arr_kiri, int arr_kanan, int right) { vector<int> temp; temp.insert(temp.end(), arr.begin() + left, arr.begin() + arr_kiri + 1); temp.insert(temp.end(), arr.begin() + arr_kiri + 1, arr.begin() + arr_kanan + 1); temp.insert(temp.end(), arr.begin() + arr_kanan + 1, arr.begin() + right + 1); sort(temp.begin(), temp.end()); for (int i = left; i <= right; i++) { arr[i] = temp[i - left]; } } void threeWayMergeSort(vector<int>& arr, int left, int right) { if (left < right) { int size = right - left + 1; int arr_kiri = left + size / 3; int arr_kanan = left + 2 * size / 3; threeWayMergeSort(arr, left, arr_kiri); 12 threeWayMergeSort(arr, arr_kiri + 1, arr_kanan); threeWayMergeSort(arr, arr_kanan + 1, right); merge(arr, left, arr_kiri, arr_kanan, right); } } void printArray(const vector<int>& arr) { for (int i = 0; i < arr.size(); i++) { cout << arr[i] << " "; } cout << endl; } int main() { system("CLS"); int n; cout << "Masukkan size dari deret bilangan: "; cin >> n; vector<int> arr(n); for (int i = 0; i < n; i++) { cin >> arr[i]; } cout << "Array awal: "; printArray(arr); threeWayMergeSort(arr, 0, arr.size() - 1); cout << "Array yang telah diurutkan: "; printArray(arr); return 0; } 13 Output: C. Bucket sort Bucket sort adalah algoritma pengurutan yang membagi elemen-elemen yang akan diurutkan ke dalam sejumlah "ember" atau "bucket" berdasarkan nilai-nilai mereka, kemudian mengurutkan setiap bucket secara terpisah menggunakan algoritma pengurutan lain atau rekursif. Setelah semua bucket terurut, elemen-elemen dari semua bucket digabungkan menjadi satu array hasil yang terurut. Algoritma bucket sort: 1. Diketahui array data sebagai berikut 2. Kemudian buat lagi array dengan size 10 sebagai ember atau tempat penampungannya 3. Kemudian kalikan masing masing array input dengan 10 kemudian dimasukkan kedalam ember yang sesuai dengan indeks rentang, contoh 0.23 dikali 10 = 2.3, sehingga masuk ke ember dengan indeks 2 14 Begitu pula dengan input data yang lain. 4. Kemudian dilakukan penyortiran lagi dimasing masing bucket dengan in-built sorting. Contohnya dengan quicksort 5. Terakhir elemen elemen dalam bucket dijadikan satu dalam array originalnya. Elemen dari bucket dihapus setelah disalin ke dalam array asli. • Kelebihan: 1. Sederhana untuk diimplementasikan: Bucket sort relatif mudah untuk diimplementasikan, terutama jika rentang nilai elemen yang diurutkan dapat diprediksi. 2. Efisien untuk sejumlah kecil data: Bucket sort dapat menjadi pilihan yang efisien ketika jumlah data yang diurutkan tidak terlalu besar dan distribusi nilainya merata. 3. Efisien untuk data dengan distribusi merata: Jika nilai-nilai yang diurutkan tersebar secara merata di seluruh rentang nilai, bucket sort dapat bekerja dengan sangat efisien. 15 • Kekurangan: 1. Tidak efisien untuk data dengan distribusi tidak merata: Jika distribusi nilai tidak merata, misalnya jika terdapat cluster besar nilai-nilai yang mendekati satu sama lain, bucket sort dapat menjadi tidak efisien karena bucket yang terisi akan berukuran besar. 2. Membutuhkan banyak memori: Bucket sort memerlukan alokasi memori tambahan untuk menyimpan bucket-bucket, yang dapat menjadi mahal dalam hal penggunaan memori. 3. Keterbatasan pada tipe data: Bucket sort lebih cocok untuk data numerik yang dapat dibagi menjadi rentang nilai. Untuk tipe data non-numerik atau data dengan kunci pencarian kompleks, bucket sort mungkin tidak efektif. 4. Diperlukan penyesuaian pada algoritma pengurutan bucket: Untuk mengurutkan setiap bucket, diperlukan algoritma pengurutan tambahan seperti insertion sort atau mergesort. Pemilihan algoritma ini dapat mempengaruhi kinerja bucket sort secara keseluruhan. Bucket sort cocok digunakan dalam kasus-kasus di mana distribusi nilai merata dan jumlah data tidak terlalu besar. Namun, untuk kasus-kasus lainnya, terutama dengan distribusi nilai tidak merata, ada algoritma pengurutan lain yang mungkin lebih cocok. kompleksitas waktu rata-rata dari bucket sort adalah O(n + k), di mana n adalah jumlah elemen yang diurutkan dan k adalah jumlah bucket. • Contoh Program: #include <iostream> #include <vector> #include <algorithm> using namespace std; void bucketSort(vector<float>& arr) { int n = arr.size(); if (n <= 0) return; vector<vector<float>> buckets(n); for (int i = 0; i < n; i++) { 16 int bucketIndex = n * arr[i]; buckets[bucketIndex].push_back(arr[i]); } for (int i = 0; i < n; i++) { sort(buckets[i].begin(), buckets[i].end()); } int index = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < buckets[i].size(); j++) { arr[index++] = buckets[i][j]; } } } void printArray(const vector<float>& arr) { for (int i = 0; i < arr.size(); i++) cout << arr[i] << " "; cout << endl; } int main() { system("CLS"); int n; printf("Masukkan size dari deret bilangan: "); scanf("%d", &n); vector <float> arr(n); for (int i = 0; i < n; i++) { cin >> arr[i]; } printf("Array awal: "); 17 printArray(arr); bucketSort(arr); printf("Array yang telah diurutkan: "); printArray(arr); return 0; } Output: 1.2 Searching Pencarian adalah proses mendasar untuk menemukan elemen atau item tertentu dalam kumpulan data. Kumpulan data ini dapat mengambil berbagai bentuk, seperti array, list, pohon, atau representasi terstruktur lainnya. Tujuan utama pencarian adalah untuk menentukan apakah elemen yang diinginkan ada dalam data, dan jika ada, untuk mengidentifikasi lokasi tepatnya atau mengambilnya kembali. Ini memainkan peran penting dalam berbagai tugas komputasi dan aplikasi dunia nyata, termasuk pengambilan informasi, analisis data, proses pengambilan keputusan, dan banyak lagi. A. Linear Search Algoritma Pencarian Linier, juga dikenal sebagai Sequential Search, adalah algoritma yang digunakan untuk mencari elemen tertentu dalam kumpulan data (biasanya dalam bentuk array atau list). Ini adalah pendekatan paling sederhana dalam mencari elemen, di mana algoritma secara berurutan mengunjungi dan mengecek setiap elemen dalam kumpulan data hingga menemukan elemen yang dicari atau mencapai akhir kumpulan data. Algoritma Pencarian Linier: 1. Mulailah dari elemen pertama (indeks 0) dalam kumpulan data. 2. Bandingkan elemen tersebut dengan elemen yang Anda cari. 3. Jika elemen yang dicari ditemukan, kembalikan indeks elemen tersebut. 18 4. Jika elemen yang dicari tidak ditemukan, lanjutkan ke elemen berikutnya dalam kumpulan data. 5. Ulangi langkah 2–4 hingga Anda menemukan elemen yang dicari atau mencapai akhir kumpulan data. 6. Jika Anda mencapai akhir kumpulan data tanpa menemukan elemen yang dicari, kembalikan nilai yang menunjukkan bahwa elemen tidak ditemukan (misalnya, 1). 7. Jika elemen yang dicari tidak ditemukan, lanjutkan ke elemen berikutnya dalam kumpulan data. 8. Ulangi langkah 2–4 hingga Anda menemukan elemen yang dicari atau mencapai akhir kumpulan data. 9. Jika Anda mencapai akhir kumpulan data tanpa menemukan elemen yang dicari, kembalikan nilai yang menunjukkan bahwa elemen tidak ditemukan (misalnya, 1) . Kompleksitas waktu algoritma pencarian linear adalah O(n), di mana n adalah jumlah elemen dalam array. Hal ini karena algoritma ini secara berurutan 19 memeriksa setiap elemen dalam array hingga menemukan nilai yang dicari atau mencapai akhir array. • Contoh Program: using namespace std; int search(int arr[], int N, int x) { for (int i = 0; i < N; i++) if (arr[i] == x) return i; return -1; } // Driver code int main(void) { int arr[] = { 2, 3, 4, 10, 40 }; int x = 10; int N = sizeof(arr) / sizeof(arr[0]); // Function call int result = search(arr, N, x); (result == -1) ? cout << "Element is not present in array" : cout << "Element is present at index " << result; return 0; } Output: 20 B. Binary Search Binary search adalah sebuah algoritma pencarian yang digunakan untuk mencari elemen tertentu dalam sebuah array atau daftar yang sudah diurutkan. Algoritma ini bekerja dengan membagi daftar menjadi dua bagian, kemudian memeriksa elemen tengahnya. Jika elemen yang dicari sama dengan elemen tengah ini, pencarian selesai. Jika tidak, algoritma akan menentukan apakah elemen yang dicari lebih besar atau lebih kecil dari elemen tengah, dan kemudian hanya memeriksa salah satu bagian dari daftar yang masih mungkin mengandung elemen yang dicari. Proses ini terus berlanjut hingga elemen yang dicari ditemukan atau daftar habis diperiksa. Algoritma pencarian biner: 1. Tentukan Rentang Pencarian Awal: Di awal pencarian, kita memiliki seluruh daftar sebagai rentang pencarian. Rentang ini didefinisikan dengan dua indeks, yaitu awal dan akhir, yang mengacu pada elemen pertama dan terakhir dalam daftar. 2. Hitung Elemen Tengah: Temukan indeks tengah di dalam rentang pencarian dengan rumus tengah = (awal + akhir) / 2. 3. Periksa Elemen Tengah: Bandingkan elemen tengah dengan elemen yang ingin Anda cari. Jika elemen tengah sama dengan elemen yang dicari, maka pencarian selesai, dan Anda telah menemukan elemennya. 4. Perkecil Rentang Pencarian: Jika elemen tengah lebih besar dari elemen yang dicari, maka Anda dapat memastikan bahwa elemen yang dicari hanya mungkin ada di sebelah kiri elemen tengah. Oleh karena itu, perkecil rentang pencarian menjadi antara awal dan tengah - 1. Jika elemen tengah lebih kecil, perkecil rentang menjadi antara tengah + 1 dan akhir. 5. Ulangi Langkah 2–4: Ulangi proses ini sampai Anda menemukan elemen yang dicari atau rentang pencarian menjadi kosong. Algoritma ini terus membagi rentang pencarian menjadi setengah hingga elemen yang dicari ditemukan atau rentang habis. Hal ini menghasilkan kompleksitas waktu O(log n), di mana n adalah jumlah elemen dalam daftar. Ini sangat efisien dibandingkan dengan pencarian linear yang memiliki kompleksitas waktu O(n). 21 • Contoh Program: using namespace std; // An iterative binary search function. int binarySearch(int arr[], int low, int high, int x) { while (low <= high) { int mid = low + (high - low) / 2; // Check if x is present at mid if (arr[mid] == x) return mid; // If x greater, ignore left half if (arr[mid] < x) low = mid + 1; // If x is smaller, ignore right half else high = mid - 1; } // If we reach here, then element was not present 22 return -1; } // Driver code int main(void) { int arr[] = { 2, 3, 4, 10, 40 }; int x = 10; int n = sizeof(arr) / sizeof(arr[0]); int result = binarySearch(arr, 0, n - 1, x); (result == -1) ? cout << "Element is not present in array" : cout << "Element is present at index " << result; return 0; } Output: C. Jump Search Seperti Pencarian Biner, Jump search adalah algoritma pencarian untuk array yang telah disorting. Ide dasarnya adalah memeriksa elemen yang lebih sedikit (dibandingkan dengan linear search) dengan melompat ke depan dengan langkahlangkah tetap atau melewatkan beberapa elemen alih-alih menelusuri semua elemen. Misalnya, kita mempunyai array arr[] berukuran n dan sebuah blok (yang akan dilompati) berukuran m. Kemudian kita cari di indeks arr[0], arr[m], arr[2m]…..arr[km], dan seterusnya. Setelah kita menemukan intervalnya (arr[km] < x < arr[(k+1)m]), kia melakukan operasi pencarian linier dari indeks km untuk menemukan elemen x. Algoritma Jump Search: Misal ada array (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610). Panjang array adalah 16. Pencarian Jump akan menemukan nilai 55 dengan langkah sebagai berikut dengan asumsi ukuran blok yang akan dilompati adalah 4. 23 1. 2. 3. 4. Lompat dari indeks 0 ke indeks 4; Lompat dari indeks 4 ke indeks 8; Lompat dari indeks 8 ke indeks 12; Karena elemen pada indeks 12 lebih besar dari 55, kita akan mundur satu langkah ke indeks 8. 5. Lakukan pencarian linier dari indeks 8 untuk mendapatkan elemen 55. Jika kita bandingkan dengan pencarian linier dan biner maka hasilnya lebih baik dari pencarian linier tetapi tidak lebih baik dari pencarian biner. Urutan peningkatan kinerjanya adalah: pencarian linier < pencarian lompat < pencarian biner Visualisasi Jump Search Kompleksitas waktu jump search adalah O(√n), di mana n adalah jumlah elemen dalam array. • Contoh Program: #include <bits/stdc++.h> using namespace std; int jumpSearch(int arr[], int x, int n) { // Finding block size to be jumped int step = sqrt(n); // Finding the block where element is // present (if it is present) int prev = 0; while (arr[min(step, n)-1] < x) 24 { prev = step; step += sqrt(n); if (prev >= n) return -1; } // Doing a linear search for x in block // beginning with prev. while (arr[prev] < x) { prev++; // If we reached next block or end of // array, element is not present. if (prev == min(step, n)) return -1; } // If element is found if (arr[prev] == x) return prev; return -1; } // Driver program to test function int main() { int arr[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610 }; int x = 55; int n = sizeof(arr) / sizeof(arr[0]); // Find the index of 'x' using Jump Search int index = jumpSearch(arr, x, n); // Print the index where 'x' is located cout << "\nNumber " << x << " is at index " << index; return 0; } 25 Output: 26