πŸ”— Single Linked List

Struktur Data dan Algoritma

Pertemuan 03

Universitas Pertahanan RI

🎯 Tujuan Pembelajaran

Setelah pertemuan ini, mahasiswa mampu:

  1. Menjelaskan konsep linked list dan komponen penyusunnya
  2. Membandingkan karakteristik array dan linked list
  3. Mengimplementasikan struktur Node dalam C++
  4. Mengimplementasikan operasi insert, delete, search, traversal
  5. Menganalisis kompleksitas waktu setiap operasi

πŸ“‹ Agenda

  1. Pendahuluan & Motivasi
  2. Konsep Linked List
  3. Array vs Linked List
  4. Implementasi Node
  5. Operasi Single Linked List
  6. Analisis Kompleksitas
  7. Aplikasi Pertahanan

1. Pendahuluan

Keterbatasan Array

⚠️ Keterbatasan Array

  1. Ukuran tetap (static)
    Ukuran harus ditentukan saat kompilasi/alokasi
  2. Insert/Delete tidak efisien
    Menyisipkan di tengah memerlukan pergeseran β†’ O(n)
  3. Pemborosan memori
    Alokasi berlebih β†’ terbuang; terlalu kecil β†’ perlu realokasi

πŸ’‘ Solusi: Linked List

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

2. Konsep Linked List

Komponen Penyusun

πŸ“¦ Struktur Node

Node adalah unit dasar linked list:

1. Data field
Menyimpan nilai/informasi

2. Pointer field (next)
Menyimpan alamat node berikutnya

42

πŸ–ΌοΈ Visualisasi Node

πŸ“Š

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)

πŸ”‘ Komponen Penting

Head Pointer

Pointer ke node pertama. Satu-satunya akses masuk ke linked list.

Tail Pointer (Opsional)

Pointer ke node terakhir. Mempercepat insert di akhir: O(n) β†’ O(1)

πŸ”— Single Linked List

head β†’
10
β†’
20
β†’
30
β†’ NULL

Traversal hanya dapat dilakukan satu arah: head β†’ tail

3. Array vs Linked List

Perbandingan Karakteristik

πŸ’Ύ Penyimpanan di Memori

πŸ—‚οΈ

p03-01-array-vs-linkedlist-memory.png

Gambar 1.1: Perbandingan penyimpanan Array dan Linked List di memori

Array: Contiguous (berurutan)
Linked List: Non-contiguous (tersebar)

πŸ“Š Perbandingan Kompleksitas

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

βš–οΈ Kapan Menggunakan?

βœ… Array

  • Ukuran data tetap/diketahui
  • Akses random sering
  • Cache performance penting

βœ… Linked List

  • Ukuran data dinamis
  • Insert/delete sering di awal
  • Tidak perlu akses random

πŸŽ–οΈ Studi Kasus Pertahanan

Sistem radar perlu menyimpan data pesawat yang terdeteksi. Data sering ditambah/dihapus secara dinamis. Pilih struktur data yang tepat!

Jawaban: Linked List

  • Jumlah pesawat dinamis (bisa bertambah/berkurang)
  • Insert & delete yang sering lebih efisien
  • Tidak ada pemborosan memori

4. Implementasi Node

Kode C++

πŸ’» Struct Node


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

πŸ”¨ Membuat Node Baru


// Menggunakan constructor
Node* newNode = new Node(10);

// Atau secara manual
Node* anotherNode = new Node;
anotherNode->data = 20;
anotherNode->next = nullptr;
                    

πŸ§ͺ Contoh: Membuat Linked List


// 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;
                    
head β†’
5
β†’
10
β†’
15
β†’ NULL

5. Operasi Linked List

Traversal & Display

🚢 Traversal

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)

5. Operasi Linked List

Insert Operations

βž• Insert di Awal

1 Buat node baru
2 Set newNode->next = head
3 Update head = newNode

void insertAtBeginning(Node*& head, int value) {
    Node* newNode = new Node(value);
    newNode->next = head;
    head = newNode;
}
                    

O(1)

πŸ–ΌοΈ Visualisasi Insert di Awal

πŸ“ˆ

p03-04-insert-at-beginning.png

Gambar 5.1: Operasi Insert di Awal Single Linked List

✏️ Contoh Insert di Awal

Sebelum:

head→
10
β†’
20
β†’ NULL

insertAtBeginning(5)

head→
5
β†’
10
β†’
20
β†’ NULL

βž• Insert di Akhir


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

πŸ–ΌοΈ Visualisasi Insert di Akhir

πŸ“ˆ

p03-05-insert-at-end.png

Gambar 5.2: Operasi Insert di Akhir Single Linked List

βž• Insert di Posisi Tertentu


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)

πŸ–ΌοΈ Visualisasi Insert di Tengah

πŸ“ˆ

p03-06-insert-at-position.png

Gambar 5.3: Operasi Insert di Posisi Tertentu

5. Operasi Linked List

Delete Operations

βž– Delete di Awal


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)

⚠️ Kesalahan Umum Delete

SALAH:


delete head;
head = head->next;  // ❌ UNDEFINED BEHAVIOR!
                        

BENAR:


Node* temp = head;
head = head->next;  // βœ… Update dulu
delete temp;        // βœ… Baru hapus
                        

πŸ–ΌοΈ Visualisasi Delete di Awal

πŸ“‰

p03-07-delete-at-beginning.png

Gambar 5.4: Operasi Delete di Awal Single Linked List

βž– Delete di Akhir


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)

🧠 Quiz: Kondisi Loop

Mengapa delete di akhir menggunakan:

current->next->next != nullptr

bukan current->next != nullptr?

Kita perlu berhenti di node kedua terakhir agar bisa:

  • Mengakses node terakhir: current->next
  • Mengubah pointer: current->next = nullptr

5. Operasi Linked List

Search & Find

πŸ” Search


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

🎯 Two Pointer Technique

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;
}
                    

πŸ–ΌοΈ Two Pointer Visualization

πŸ‘†πŸ‘†

p03-08-kth-from-end-two-pointers.png

Gambar 3.8: Two-pointer technique untuk elemen ke-k dari belakang

6. Ringkasan Kompleksitas

Big-O Analysis

πŸ“Š Kompleksitas Waktu

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

βš–οΈ Keunggulan vs Kelemahan

βœ… Keunggulan

  • Ukuran dinamis
  • Insert/delete di awal O(1)
  • Tidak ada pemborosan memori

❌ Kelemahan

  • Tidak ada random access
  • Memory overhead (pointer)
  • Cache performance kurang

πŸŽ–οΈ 7. Aplikasi Pertahanan

Studi Kasus Militer

πŸ“‘ Radar Log Buffer

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!

πŸ›‘οΈ Aplikasi Lainnya

  • Manajemen Antrian Pesan
    Pesan komunikasi militer (FIFO)
  • Tracking Target
    Daftar pesawat/kapal yang terdeteksi radar
  • Undo History
    Sistem command & control (LIFO)
  • Sensor Network
    Linked list sensor di perimeter pertahanan

πŸ“ Ringkasan

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

❓ Pertanyaan?

Silakan bertanya atau diskusi

Referensi: Cormen Ch.10.2 | Weiss Ch.3 | Hubbard Ch.7

Terima Kasih! πŸ™

Struktur Data dan Algoritma

Pertemuan 03: Single Linked List

Β© 2026 - CC BY 4.0