Pertemuan 03
Universitas Pertahanan RI
Setelah pertemuan ini, mahasiswa mampu:
Node dalam C++O(n)Linked List adalah struktur data linear yang terdiri dari node yang saling terhubung melalui pointer.
β Ukuran dinamis
β Insert/delete efisien di awal
β Tidak ada pemborosan memori
Node adalah unit dasar linked list:
1. Data field
Menyimpan nilai/informasi
2. Pointer field (next)
Menyimpan alamat node berikutnya
π
p03-02-node-structure.png
Gambar 1.2: Struktur Node dalam Single Linked List
Node terdiri dari data (nilai) dan next (pointer ke node berikutnya)
Pointer ke node pertama. Satu-satunya akses masuk ke linked list.
Pointer ke node terakhir. Mempercepat insert di akhir: O(n) β O(1)
Traversal hanya dapat dilakukan satu arah: head β tail
ποΈ
p03-01-array-vs-linkedlist-memory.png
Gambar 1.1: Perbandingan penyimpanan Array dan Linked List di memori
| Operasi | Array | Linked List |
|---|---|---|
| Akses Elemen | O(1) | O(n) |
| Insert di Awal | O(n) | O(1) |
| Insert di Akhir | O(1)* | O(n) / O(1)** |
| Delete di Awal | O(n) | O(1) |
| Search | O(n) | O(n) |
* jika ada ruang ** dengan tail pointer
Sistem radar perlu menyimpan data pesawat yang terdeteksi. Data sering ditambah/dihapus secara dinamis. Pilih struktur data yang tepat!
Jawaban: Linked List
struct Node {
int data; // Data yang disimpan
Node* next; // Pointer ke node berikutnya
// Constructor
Node(int value) : data(value), next(nullptr) {}
};
Constructor otomatis set next = nullptr
// Menggunakan constructor
Node* newNode = new Node(10);
// Atau secara manual
Node* anotherNode = new Node;
anotherNode->data = 20;
anotherNode->next = nullptr;
// Buat tiga node
Node* node1 = new Node(5);
Node* node2 = new Node(10);
Node* node3 = new Node(15);
// Hubungkan node-node
node1->next = node2; // node1 -> node2
node2->next = node3; // node2 -> node3
// node3->next sudah nullptr
// Set head
Node* head = node1;
Traversal = mengunjungi setiap node dari head hingga NULL
void display(Node* head) {
Node* current = head;
while (current != nullptr) {
cout << current->data << " -> ";
current = current->next;
}
cout << "NULL" << endl;
}
Kompleksitas: O(n)
newNode->next = head
head = newNode
void insertAtBeginning(Node*& head, int value) {
Node* newNode = new Node(value);
newNode->next = head;
head = newNode;
}
O(1)
π
p03-04-insert-at-beginning.png
Gambar 5.1: Operasi Insert di Awal Single Linked List
Sebelum:
insertAtBeginning(5)
void insertAtEnd(Node*& head, int value) {
Node* newNode = new Node(value);
// Kasus list kosong
if (head == nullptr) {
head = newNode;
return;
}
// Traversal ke node terakhir
Node* current = head;
while (current->next != nullptr) {
current = current->next;
}
// Hubungkan
current->next = newNode;
}
O(n) tanpa tail pointer
π
p03-05-insert-at-end.png
Gambar 5.2: Operasi Insert di Akhir Single Linked List
void insertAtPosition(Node*& head, int value, int pos) {
if (pos == 0) { insertAtBeginning(head, value); return; }
// Traversal ke posisi (pos - 1)
Node* prev = head;
for (int i = 0; i < pos - 1; i++) {
prev = prev->next;
}
// Sisipkan node baru
Node* newNode = new Node(value);
newNode->next = prev->next;
prev->next = newNode;
}
O(n)
π
p03-06-insert-at-position.png
Gambar 5.3: Operasi Insert di Posisi Tertentu
void deleteAtBeginning(Node*& head) {
if (head == nullptr)
throw runtime_error("List kosong!");
Node* temp = head; // Simpan node
head = head->next; // Update head
delete temp; // Hapus node
}
O(1)
SALAH:
delete head;
head = head->next; // β UNDEFINED BEHAVIOR!
BENAR:
Node* temp = head;
head = head->next; // β
Update dulu
delete temp; // β
Baru hapus
π
p03-07-delete-at-beginning.png
Gambar 5.4: Operasi Delete di Awal Single Linked List
void deleteAtEnd(Node*& head) {
if (head == nullptr) throw runtime_error("List kosong!");
// Kasus hanya satu node
if (head->next == nullptr) {
delete head;
head = nullptr;
return;
}
// Traversal ke node kedua terakhir
Node* current = head;
while (current->next->next != nullptr) {
current = current->next;
}
delete current->next;
current->next = nullptr;
}
O(n)
Mengapa delete di akhir menggunakan:
current->next->next != nullptr
bukan current->next != nullptr?
Kita perlu berhenti di node kedua terakhir agar bisa:
current->nextcurrent->next = nullptr
bool search(Node* head, int value) {
Node* current = head;
while (current != nullptr) {
if (current->data == value) {
return true; // Ditemukan
}
current = current->next;
}
return false; // Tidak ditemukan
}
O(n) - worst case semua node
Mencari elemen ke-k dari belakang dengan satu kali traversal:
int findKthFromEnd(Node* head, int k) {
Node* fast = head;
Node* slow = head;
// Majukan fast k langkah
for (int i = 0; i < k; i++) {
fast = fast->next;
}
// Majukan bersamaan sampai fast = NULL
while (fast != nullptr) {
fast = fast->next;
slow = slow->next;
}
return slow->data;
}
ππ
p03-08-kth-from-end-two-pointers.png
Gambar 3.8: Two-pointer technique untuk elemen ke-k dari belakang
| Operasi | Kompleksitas | Keterangan |
|---|---|---|
| Traversal | O(n) | Mengunjungi semua node |
| Search | O(n) | Worst case: elemen tidak ada |
| Insert Beginning | O(1) | Konstan |
| Insert End | O(n) | O(1) dengan tail |
| Insert Position | O(n) | Traversal ke posisi |
| Delete Beginning | O(1) | Konstan |
| Delete End | O(n) | Perlu node kedua terakhir |
Sistem log aktivitas radar dengan circular buffer:
struct RadarLog {
time_t timestamp;
string activity;
RadarLog* next;
};
class RadarLogBuffer {
private:
RadarLog* head;
RadarLog* tail;
int maxSize, currentSize;
public:
void addLog(string activity); // O(1)
void displayLogs(); // O(n)
};
Ketika penuh, data lama otomatis tertimpa!
| Konsep | Poin Penting |
|---|---|
| Linked List | Node terhubung via pointer, ukuran dinamis |
| Node | Terdiri dari data + pointer next |
| Head | Pointer ke node pertama (satu-satunya akses) |
| Insert Awal | O(1) - paling efisien |
| Delete Awal | O(1) - simpan temp dulu! |
| Search/Traversal | O(n) - harus linear |
Silakan bertanya atau diskusi
Referensi: Cormen Ch.10.2 | Weiss Ch.3 | Hubbard Ch.7
Struktur Data dan Algoritma
Pertemuan 03: Single Linked List
Β© 2026 - CC BY 4.0