Double Linked List
Meningkatkan fleksibilitas struktur data dengan pointer ganda untuk navigasi dua arah, dilengkapi penunjuk First dan Last.
Motivasi
Pada materi sebelumnya, kita mengibaratkan Single Linked List seperti rangkaian gerbong kereta api. Sayangnya, desain Single ibarat gerbong yang pintunya hanya bisa dilewati satu arah: Anda bisa berjalan dari lokomotif ke gerbong paling belakang, tetapi tidak bisa berjalan mundur kembali ke lokomotif. Jika Anda terlewat satu gerbong saat mencari tempat duduk, Anda harus turun, kembali ke lokomotif, dan mengulang pencarian dari awal.
Double Linked List memecahkan masalah ini dengan menambahkan satu pointer lagi. Setiap Node kini memiliki kemampuan melihat siapa elemen setelahnya dan siapa elemen sebelumnya.
Selain itu, kita juga menambahkan penunjuk di bagian ekor (Last). Jika sebelumnya kita harus menelusuri ratusan elemen satu per satu hanya untuk menambahkan data di akhir, kini kita bisa langsung melompat ke belakang karena posisi elemen terakhir sudah dicatat secara eksplisit di pointer Last.
Konsep Inti
Elemen List berpointer ganda memiliki tiga atribut utama:
info: Menyimpan nilai data yang sebenarnya.next: Menyimpan alamat elemen selanjutnya.prev: Menyimpan alamat elemen sebelumnya.
Kondisi List dikenali dari dua penunjuk utama: first dan last.
- Jika
Listkosong:firstbernilaiNULLdanlastbernilaiNULL. - Jika
Listhanya berisi 1 elemen: pointerfirstdanlastmenunjuk keNodeyang sama, sementaraprevdannextgerbong tersebut bernilaiNULL.
Perbandingan Struktur
| Aspek | Single Linked List | Double Linked List |
|---|---|---|
| Navigasi | Satu arah (maju saja) | Dua arah (maju dan mundur) |
| Penambahan di Akhir | O(n) - Harus menelusuri dari awal | O(1) - Langsung menggunakan pointer last |
| Pencarian Sebelumnya | Sulit (Harus mengulang dari awal) | Sangat mudah (Tinggal panggil Node->prev) |
| Penggunaan Memori | Hemat (1 pointer per node) | Lebih boros (2 pointer per node) |
Operasi Dasar
Karena setiap elemen memiliki dua lengan (prev dan next), operasi penyambungan dan pemutusan rantai menjadi lebih banyak secara logika. Anda tidak boleh hanya mengurus satu arah, melainkan kedua arahnya.
Menambah di Awal
Berikut adalah logika untuk operasi InsertFirst:
void InsertFirst(List *L, int x) {
Node *N = Allocation(x);
if (N != NULL) {
N->next = L->first;
if (!IsEmpty(L)) {
// Jika list sudah ada isinya, gerbong pertama lama menunjuk mundur ke gerbong baru
L->first->prev = N;
} else {
// Jika list kosong, maka gerbong baru ini juga sekaligus menjadi Last
L->last = N;
}
// Pindahkan gelar First ke gerbong baru
L->first = N;
}
}
Awas Segmentation Fault!
Kondisi if (!IsEmpty(L)) sangatlah krusial. Jika list masih kosong (first bernilai NULL), dan Anda memaksa mengakses L->first->prev, program akan crash. Selalu amankan operasi pointer Anda dengan pengecekan kondisi kosong!
Navigasi Maju dan Mundur
Keunggulan utama struktur ini adalah fleksibilitas pembacaan data. Kita bisa mencetak data secara terbalik dengan memulai dari pointer last dan menelusuri mundur menggunakan prev.
void PrintMaju(List L) {
cout << "Dari Depan : ";
Node *temp = L.first;
while (temp != NULL) {
cout << temp->info << " ";
temp = temp->next;
}
cout << "\n";
}
void PrintMundur(List L) {
cout << "Dari Belakang: ";
Node *temp = L.last;
while (temp != NULL) {
cout << temp->info << " ";
temp = temp->prev;
}
cout << "\n";
}
Navigasi Riwayat:
Fitur Undo (Ctrl+Z) dan Redo (Ctrl+Y) atau tombol Back/Forward di browser sangat cocok diimplementasikan menggunakan konsep Double Linked List!