Program
Linked list adalah struktur data yang berperan penting dalam pengorganisasian dan pengelolaan data. Struktur ini berisi serangkaian node yang disimpan pada lokasi acak di memori, sehingga memungkinkan manajemen memori yang efisien. Setiap node dalam linked list memiliki dua komponen utama: bagian data dan referensi ke node berikutnya dalam urutan.
Jika konsep ini terlihat rumit pada pandangan pertama, jangan khawatir!
Kita akan menguraikannya dari dasar untuk menjelaskan apa itu linked list, mengapa kita menggunakannya, dan keunggulan unik yang ditawarkannya.
Mengapa Linked List?
Linked list diciptakan untuk mengatasi berbagai kekurangan yang terkait dengan penyimpanan data dalam list dan array biasa, seperti yang diuraikan di bawah ini:
Kemudahan penyisipan dan penghapusan
Dalam list, menyisipkan atau menghapus elemen pada posisi selain di akhir mengharuskan penggeseran semua item setelahnya ke posisi berbeda. Proses ini memiliki kompleksitas waktu O(n) dan dapat menurunkan kinerja secara signifikan, terutama saat ukuran list bertambah. Jika Anda belum familiar dengan cara kerja list atau implementasinya, Anda dapat membaca tutorial kami tentang list di Python.
Linked list, sebaliknya, bekerja berbeda. Struktur ini menyimpan elemen pada berbagai lokasi memori yang tidak berurutan dan menghubungkannya melalui pointer ke node berikutnya. Struktur ini memungkinkan linked list menambah atau menghapus elemen di posisi mana pun hanya dengan memodifikasi tautan untuk memasukkan elemen baru atau melewati elemen yang dihapus.
Setelah Anda memiliki referensi langsung ke node di titik penyisipan atau penghapusan, operasinya sendiri adalah O(1). Namun, menemukan posisi tersebut tetap memerlukan penelusuran O(n), sehingga manfaat O(1) hanya berlaku saat Anda sudah memegang pointer ke node yang relevan (seperti saat bekerja di head list).
Ukuran dinamis
List Python adalah array dinamis, artinya memberikan fleksibilitas untuk mengubah ukuran.
Namun, proses ini melibatkan serangkaian operasi kompleks, termasuk realokasi array ke blok memori baru yang lebih besar. Realokasi seperti ini tidak efisien karena elemen harus disalin ke blok baru, berpotensi mengalokasikan ruang lebih besar daripada yang segera diperlukan.
Sebaliknya, linked list dapat bertambah dan menyusut secara dinamis tanpa perlu realokasi atau pengubahan ukuran. Ini menjadikannya pilihan yang lebih disukai untuk tugas yang memerlukan fleksibilitas tinggi.
Efisiensi memori
List mengalokasikan memori untuk semua elemennya dalam satu blok yang berurutan. Jika list perlu bertambah melampaui ukuran awalnya, list harus mengalokasikan blok memori berurutan baru yang lebih besar dan kemudian menyalin semua elemen yang ada ke blok baru ini. Proses ini memakan waktu dan tidak efisien, terutama untuk list besar. Di sisi lain, jika ukuran awal list terlalu besar, memori yang tidak digunakan menjadi terbuang.
Sebaliknya, linked list mengalokasikan memori untuk setiap elemen secara terpisah. Struktur ini menghasilkan pemanfaatan memori yang lebih baik karena memori untuk elemen baru dapat dialokasikan saat elemen tersebut ditambahkan.
Kapan Sebaiknya Menggunakan Linked List?
Walaupun linked list memberikan manfaat tertentu dibanding list dan array biasa, seperti ukuran dinamis dan efisiensi memori, linked list juga memiliki keterbatasan. Karena pointer untuk setiap elemen harus disimpan untuk mereferensikan node berikutnya, penggunaan memori per elemen lebih tinggi saat menggunakan linked list. Selain itu, struktur data ini tidak memungkinkan akses langsung ke data. Mengakses sebuah elemen memerlukan penelusuran berurutan dari awal list, menghasilkan kompleksitas waktu pencarian O(n).
Pilihan antara menggunakan linked list atau array bergantung pada kebutuhan spesifik aplikasi. Linked list paling berguna ketika:
- Anda perlu sering menyisipkan dan menghapus banyak elemen
- Ukuran data tidak dapat diprediksi atau kemungkinan sering berubah
- Akses langsung ke elemen bukan persyaratan
- Dataset berisi elemen atau struktur berukuran besar
Jenis-jenis linked list
Ada tiga jenis linked list, masing-masing menawarkan keunggulan unik untuk skenario yang berbeda. Jenis-jenis tersebut adalah:
Singly-linked list

Singly-linked list
Singly-linked list adalah jenis linked list paling sederhana, di mana setiap node berisi sejumlah data dan referensi ke node berikutnya dalam urutan. Struktur ini hanya dapat ditelusuri dalam satu arah — dari head (node pertama) ke tail (node terakhir).
Setiap node dalam singly-linked list biasanya terdiri dari dua bagian:
- Data: Informasi sebenarnya yang disimpan dalam node.
- Next Pointer: Referensi ke node berikutnya. Next pointer pada node terakhir biasanya diatur ke null.
Karena struktur data ini hanya dapat ditelusuri dalam satu arah, mengakses elemen tertentu berdasarkan nilai atau indeks mengharuskan memulai dari head dan bergerak secara berurutan melalui node hingga node yang diinginkan ditemukan. Operasi ini memiliki kompleksitas waktu O(n), sehingga kurang efisien untuk list yang besar.
Menyisipkan dan menghapus node di awal singly-linked list sangat efisien dengan kompleksitas waktu O(1). Namun, penyisipan dan penghapusan di tengah atau di akhir memerlukan penelusuran list hingga titik tersebut, sehingga kompleksitas waktunya menjadi O(n).
Desain singly-linked list menjadikannya struktur data yang berguna saat melakukan operasi yang terjadi di awal list.
Doubly-linked list

Doubly-linked list
Salah satu kelemahan singly-linked list adalah kita hanya dapat menelusurinya dalam satu arah dan tidak dapat kembali ke node sebelumnya jika diperlukan. Batasan ini membatasi kemampuan kita untuk melakukan operasi yang memerlukan navigasi dua arah.
Doubly-linked list mengatasi masalah ini dengan menambahkan pointer tambahan dalam setiap node, sehingga list dapat ditelusuri dalam kedua arah. Setiap node dalam doubly-linked list berisi tiga elemen: data, pointer ke node berikutnya, dan pointer ke node sebelumnya.
Circular linked list

Circular linked list
Circular linked list adalah bentuk khusus dari linked list di mana node terakhir menunjuk kembali ke node pertama, menciptakan struktur melingkar. Ini berarti, tidak seperti singly dan doubly linked list yang telah kita lihat sejauh ini, circular linked list tidak berakhir; alih-alih, ia berputar terus.
Sifat siklik pada circular linked list membuatnya ideal untuk skenario yang perlu dilalui secara terus-menerus, seperti permainan papan yang kembali dari pemain terakhir ke pemain pertama, atau dalam algoritme komputasi seperti penjadwalan round-robin.
Ringkasan kompleksitas waktu
Akan berguna untuk melihat perbandingan cepat antara linked list dan list Python:
| Operasi | Singly Linked List | Array/List Python |
|---|---|---|
| Akses berdasarkan indeks | O(n) | O(1) |
| Pencarian berdasarkan nilai | O(n) | O(n) |
| Sisip di awal | O(1) | O(n) |
| Sisip di akhir | O(n) | O(1) diamortisasi |
| Sisip di tengah | O(n) | O(n) |
| Hapus di awal | O(1) | O(n) |
| Hapus di akhir | O(n) | O(1) diamortisasi |
Inti utamanya: linked list unggul dalam penyisipan dan penghapusan di head (O(1)), tetapi kalah dalam hal lainnya. Jika Anda tidak sering menambah atau menghapus elemen di awal struktur data, list Python biasa kemungkinan adalah pilihan yang lebih baik.
Cara Membuat Linked List di Python
Sekarang kita memahami apa itu linked list, mengapa kita menggunakannya, dan variasinya, mari lanjutkan mengimplementasikan struktur data ini di Python. Notebook untuk tutorial ini juga tersedia di DataLab workbook ini; jika Anda membuat salinannya, Anda dapat mengedit dan menjalankan kodenya. Ini adalah pilihan yang bagus jika Anda mengalami masalah saat menjalankan kode sendiri!
Inisialisasi node
Seperti yang telah kita pelajari, node adalah elemen dalam linked list yang menyimpan data dan referensi ke node berikutnya dalam urutan. Berikut cara Anda dapat mendefinisikan node di Python:
class Node:
def __init__(self, data):
self.data = data
self.next = None
def __repr__(self):
return f"Node({self.data})"
Kode di atas menginisialisasi node dengan melakukan dua tindakan utama: Atribut "data" pada node diberi nilai yang mewakili informasi aktual yang ingin disimpan node tersebut. Atribut "next" mewakili alamat node berikutnya. Saat ini diatur ke None, menandakan bahwa node tersebut belum terhubung ke node lain dalam list. Saat kita terus menambahkan node baru ke linked list, atribut ini akan diperbarui untuk menunjuk ke node berikutnya.
Membuat kelas linked list
Selanjutnya, kita perlu membuat kelas linked list. Kelas ini akan membungkus semua operasi untuk mengelola node, seperti penyisipan dan penghapusan. Kita akan mulai dengan menginisialisasi linked list:
class LinkedList:
def __init__(self):
self.head = None # Initialize head as None
Dengan mengatur self.head ke None, kita menyatakan bahwa linked list pada awalnya kosong dan belum ada node dalam list yang dapat ditunjuk. Sekarang kita akan melanjutkan untuk mengisi list dengan menyisipkan node baru.
Menyisipkan node baru di awal linked list
Di dalam kelas LinkedList, kita akan menambahkan metode untuk membuat node baru dan menempatkannya di awal list:
def insertAtBeginning(self, new_data):
new_node = Node(new_data) # Create a new node
new_node.next = self.head # Next for new node becomes the current head
self.head = new_node # Head now points to the new node
Setiap kali Anda memanggil metode di atas, sebuah node baru dibuat dengan data yang Anda tentukan. Next pointer dari node baru ini diatur ke head saat ini dari list, yang akan menempatkan node ini di depan node yang sudah ada. Terakhir, node yang baru dibuat dijadikan head dari list.
Sekarang kita akan mengisi linked list ini dengan serangkaian kata untuk memahami lebih baik bagaimana operasi penyisipan bekerja. Untuk melakukan ini, mari terlebih dahulu membuat metode yang dirancang untuk menelusuri dan mencetak isi list:
def printList(self):
temp = self.head # Start from the head of the list
while temp:
print(temp.data,end=' ') # Print the data in the current node
temp = temp.next # Move to the next node
print() # Ensures the output is followed by a new line
Metode di atas akan mencetak isi linked list kita. Sekarang mari kita gunakan metode yang telah kita definisikan untuk mengisi list dengan serangkaian kata: “the quick brown fox.”
if __name__ == '__main__':
# Create a new LinkedList instance
llist = LinkedList()
# Insert each letter at the beginning using the method we created
llist.insertAtBeginning('fox')
llist.insertAtBeginning('brown')
llist.insertAtBeginning('quick')
llist.insertAtBeginning('the')
# Now 'the' is the head of the list, followed by 'quick', then 'brown' and 'fox'
# Print the list
llist.printList()
Baris-baris kode di atas akan menghasilkan output berikut:
"the quick brown fox"
Menyisipkan node baru di akhir linked list
Sekarang kita akan membuat metode bernama insertAtEnd di dalam kelas LinkedList, untuk membuat node baru di akhir list. Jika list kosong, node baru akan menjadi head dari list. Jika tidak, node baru akan ditambahkan ke node terakhir saat ini dalam list. Mari lihat bagaimana ini bekerja dalam praktik:
def insertAtEnd(self, new_data):
new_node = Node(new_data)
if self.head is None:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
Metode di atas dimulai dengan membuat node baru. Lalu metode ini memeriksa apakah list kosong, dan jika iya, node baru ditetapkan sebagai head dari list tersebut. Jika tidak, list ditelusuri untuk menemukan node terakhir dan pointer dari node tersebut diarahkan ke node baru.
Sekarang kita perlu memasukkan metode ini ke dalam kelas LinkedList dan menggunakannya untuk menambahkan sebuah kata di akhir list kita. Untuk melakukannya, ubah fungsi utama Anda agar terlihat seperti ini:
if __name__ == '__main__':
llist = LinkedList()
# Insert words at the beginning
llist.insertAtBeginning('fox')
llist.insertAtBeginning('brown')
llist.insertAtBeginning('quick')
llist.insertAtBeginning('the')
# Insert a word at the end
llist.insertAtEnd('jumps')
# Print the list
llist.printList()
Perhatikan bahwa kita hanya memanggil metode insertAtEnd untuk mencetak kata “jumps” di akhir list. Kode di atas akan menghasilkan output berikut:
"the quick brown fox jumps"
Menghapus node dari awal linked list
Menghapus node pertama dari linked list mudah dilakukan karena hanya melibatkan pengalihan head list ini ke node kedua. Dengan demikian, node pertama tidak lagi menjadi bagian dari list. Untuk melakukannya, sertakan metode berikut dalam kelas LinkedList:
def deleteFromBeginning(self):
if self.head is None:
return "The list is empty" # If the list is empty, return this string
self.head = self.head.next # Otherwise, remove the head by making the next node the new head
Menghapus node dari akhir linked list
Untuk menghapus node terakhir dari linked list, kita harus menelusuri list untuk menemukan node kedua dari terakhir dan mengubah next pointer-nya menjadi None. Dengan demikian, node terakhir tidak lagi menjadi bagian dari list. Salin dan tempel metode berikut ke dalam kelas LinkedList Anda untuk melakukannya:
def deleteFromEnd(self):
if self.head is None:
return "The list is empty"
if self.head.next is None:
self.head = None # If there's only one node, remove the head by making it None
return
temp = self.head
while temp.next.next: # Otherwise, go to the second-last node
temp = temp.next
temp.next = None # Remove the last node by setting the next pointer of the second-last node to None
Metode di atas pertama-tama memeriksa apakah linked list kosong, dan mengembalikan pesan kepada pengguna jika memang kosong. Jika tidak, jika list hanya berisi satu node, node tersebut dihapus. Untuk list dengan beberapa node, metode akan menemukan node kedua dari terakhir, dan referensi node berikutnya diperbarui menjadi None.
Sekarang mari perbarui fungsi utama untuk menghapus elemen dari awal dan akhir linked list:
if __name__ == '__main__':
llist = LinkedList()
# Insert words at the beginning
llist.insertAtBeginning('fox')
llist.insertAtBeginning('brown')
llist.insertAtBeginning('quick')
llist.insertAtBeginning('the')
# Insert a word at the end
llist.insertAtEnd('jumps')
# Print the list before deletion
print("List before deletion:")
llist.printList()
# Deleting nodes from the beginning and end
llist.deleteFromBeginning()
llist.deleteFromEnd()
# Print the list after deletion
print("List after deletion:")
llist.printList()
Kode di atas akan mencetak list sebelum dan sesudah penghapusan, menampilkan bagaimana operasi penyisipan dan penghapusan bekerja di linked list. Anda akan melihat output berikut setelah menjalankan kode ini:
List before deletion:
the quick brown fox jumps
List after deletion:
quick brown fox
Mencari nilai tertentu dalam linked list
Operasi terakhir yang akan kita pelajari pada bab ini adalah pengambilan nilai tertentu dalam linked list. Untuk melakukannya, metode harus dimulai dari head list dan mengiterasi setiap node, memeriksa apakah data node cocok dengan nilai yang dicari. Berikut implementasi praktis dari operasi ini:
def search(self, value):
current = self.head # Start with the head of the list
position = 0 # Counter to keep track of the position
while current: # Traverse the list
if current.data == value: # Compare the list's data to the search value
return f"Value '{value}' found at position {position}" # Print the value if a match is found
current = current.next
position += 1
return f"Value '{value}' not found in the list"
Untuk menemukan nilai tertentu dalam linked list yang telah kita buat, perbarui fungsi utama Anda untuk menyertakan metode pencarian yang baru saja kita buat:
if __name__ == '__main__':
llist = LinkedList()
# Insert words at the beginning
llist.insertAtBeginning('fox')
llist.insertAtBeginning('brown')
llist.insertAtBeginning('quick')
llist.insertAtBeginning('the')
# Insert a word at the end
llist.insertAtEnd('jumps')
# Print the list before deletion
print("List before deletion:")
llist.printList()
# Deleting nodes from beginning and end
llist.deleteFromBeginning()
llist.deleteFromEnd()
# Print the list after deletion
print("List after deletion:")
llist.printList()
# Search for 'quick' and 'lazy' in the list
print(llist.search('quick')) # Expected to find
print(llist.search('lazy')) # Expected not to find
Kode di atas akan menghasilkan output berikut:
List before deletion:
the quick brown fox jumps
List after deletion:
quick brown fox
Value 'quick' found at position 0
Value 'lazy' not found in the list
Kata “quick” berhasil ditemukan dalam linked list karena berada pada posisi pertama dalam list. Namun, kata “lazy” bukan bagian dari list, sehingga tidak ditemukan.
Pemikiran Akhir
Jika Anda sudah sampai di sini, selamat! Anda sekarang memiliki pemahaman yang kuat tentang prinsip dasar linked list, termasuk strukturnya, jenis-jenisnya, cara menambah dan menghapus elemen, serta cara menelusurinya.
Namun perjalanan tidak berhenti di sini. Linked list hanyalah permulaan dari dunia struktur data dan algoritme. Berikut beberapa langkah lanjutan yang dapat Anda ambil untuk memperdalam pemahaman Anda:
Buat proyek Anda sendiri
Selami penerapan praktis linked list dengan mengintegrasikannya ke dalam proyek pemrograman atau data science. Linked list digunakan untuk membangun sistem berkas, menyusun hash table, hingga membuat sistem navigasi GPS dan permainan papan. Untuk mulai membuat proyek Anda sendiri, lihat proyek data science gratis kami yang dipandu untuk mengajarkan cara menyelesaikan masalah dunia nyata di Python, R, dan SQL.
Pelajari struktur data dan algoritme
Mempelajari struktur data lain seperti tree, stack, dan queue adalah kelanjutan alami setelah memahami linked list. Struktur-struktur ini dibangun di atas prinsip linked list, membantu Anda menyelesaikan lebih banyak masalah komputasi secara efisien. Tree dan binary search tree, misalnya, memperluas konsep linked list ke bentuk hierarkis, memungkinkan setiap node terhubung ke beberapa elemen dalam struktur data.
Jika konsep-konsep ini terdengar asing bagi Anda, jangan khawatir! Datacamp memiliki satu kursus lengkap tentang struktur data dan algoritme di Python yang akan membawa Anda melalui konsep-konsep ini secara lebih mendalam. Anda akan terlebih dahulu mempelajari struktur data seperti stack, tree, hash table, queue, dan graph. Seiring perkembangan Anda dalam kursus, Anda akan memahami algoritme pencarian dan pengurutan, yang akan membantu Anda menjadi programmer dan pemecah masalah yang lebih efisien.
Menjelajahi konsep linked list tingkat lanjut
Kita telah mengimplementasikan singly-linked list dalam tutorial ini, mencakup operasi seperti penyisipan, penghapusan, dan penelusuran.
Anda dapat melangkah lebih jauh dengan mempelajari implementasi doubly dan circular linked list. Skip list adalah perpanjangan lain dari linked list yang memungkinkan operasi pencarian lebih cepat dengan memfasilitasi akses yang lebih cepat ke elemen.
Mempelajari struktur data tingkat lanjut ini akan meningkatkan keterampilan teknis Anda dan secara dramatis memperbaiki kemampuan pemrograman Anda, mempersiapkan Anda untuk tantangan yang lebih kompleks di bidang seperti data science, pengembangan perangkat lunak, dan rekayasa machine learning.
Jika Anda menginginkan pengantar pemrograman yang lebih ramah pemula sebelum membahas topik-topik lanjutan ini, jelajahi jalur karier Python Programmer kami. Jalur ini menawarkan rangkaian kursus yang akan mengajarkan Anda dasar-dasar bahasanya.

Natassha adalah seorang konsultan data yang bekerja di persimpangan ilmu data dan pemasaran. Ia meyakini bahwa data, ketika digunakan dengan bijak, dapat menginspirasi pertumbuhan luar biasa bagi individu dan organisasi. Sebagai profesional data autodidak, Natassha suka menulis artikel yang membantu para calon praktisi ilmu data menembus industri. Artikel-artikelnya di blog pribadi, serta publikasi eksternal, meraih rata-rata 200 ribu tayangan per bulan.
