鏈結串列是基本重要的資料結構。C/C++ 靠指標實作,Java 雖無指標語法,但**物件參考本質即指標**(概念層面),反而因記憶體自動管理、型別安全,實作更簡潔優雅。
class Node {
Object data; // 使用 Object 型別支援任意資料
Node next; // 指向下一節點
Node(Object d) { data = d; next = null; }
}
維護四個關鍵欄位:
Head:首節點Tail:尾節點 (支援 O(1) 尾端插入)Pointer:**指向當前節點的前驅節點** (關鍵設計!null 代表當前為首節點)Length:節點數 (O(1) 取得大小)為何 Pointer 指向前驅而非當前? 刪除當前節點時,需修改前驅節點的 next 指向後繼節點以維持串列完整。若 Pointer 指向當前節點,刪除後將難以更新前驅連結。
輔助方法 cursor() 回傳當前節點:Pointer == null ? Head : Pointer.next。
| 方法 | 功能 |
|---|---|
reset() | 重置當前至首節點 (Pointer = null) |
isEmpty() | 判斷是否為空 (Length == 0) |
isEnd() | 判斷當前是否為尾節點 |
nextNode() | 移至下一節點並回傳其值 (Pointer = cursor()) |
currentNode() | 回傳當前節點值 |
insert(Object d) | 在當前節點**前**插入新節點,新節點成為當前 |
remove() | 移除當前節點並回傳其值,後繼節點成為當前 (若刪尾節點則回首節點) |
size() | 回傳串列大小 |
deleteAll() | 清空串列 |
import java.io.*;
public class List {
private Node Head = null, Tail = null, Pointer = null;
private int Length = 0;
public void deleteAll() { Head = Tail = Pointer = null; Length = 0; }
public void reset() { Pointer = null; }
public boolean isEmpty() { return Length == 0; }
public boolean isEnd() {
if (Length == 0) throw new NullPointerException();
if (Length == 1) return true;
return cursor() == Tail;
}
public Object nextNode() {
if (Length <= 1) throw new NoSuchElementException();
Node temp = cursor();
Pointer = temp;
if (temp != Tail) return temp.next.data;
throw new NoSuchElementException();
}
public Object currentNode() { return cursor().data; }
public void insert(Object d) {
Node e = new Node(d);
if (Length == 0) { Head = Tail = e; }
else {
Node temp = cursor();
e.next = temp;
if (Pointer == null) Head = e;
else Pointer.next = e;
}
Length++;
}
public int size() { return Length; }
public Object remove() {
if (Length == 0) throw new NoSuchElementException();
Object temp;
if (Length == 1) { temp = Head.data; deleteAll(); }
else {
Node cur = cursor();
temp = cur.data;
if (cur == Head) Head = cur.next;
else if (cur == Tail) { Pointer.next = null; Tail = Pointer; reset(); }
else Pointer.next = cur.next;
Length--;
}
return temp;
}
private Node cursor() {
if (Head == null) throw new NullPointerException();
return (Pointer == null) ? Head : Pointer.next;
}
// main() 示範基本用法:插入 1~10、遍歷列印、逐一刪除、驗證空串列
public static void main(String[] args) { ... }
}
class Node { Object data; Node next; Node(Object d) { data = d; next = null; } }
節點類別新增 previous 參考:
class Node {
Object data;
Node next, previous;
Node(Object d) { data = d; next = previous = null; }
}
操作邏輯相似,插入/刪除時同步維護 next 與 previous 兩向連結。此架構亦可直接應用於堆疊 (Stack) 與佇列 (Queue) 實作,讀者可自行嘗試修改 List 類別實現。
Java 物件參考機制讓鏈結串列實作既直觀又安全。掌握「Pointer 指向前驅」的設計精髓,能靈活處理插入刪除邊界條件。這份實作不僅是資料結構練習,更展現 Java 以高層抽象簡化底層操作的語言哲學。