鏈表是數據結構基石。本文以單鏈表為例,對比 C 語言(指針手動管理內存)與 Java(引用自動 GC)的實現差異,幫助理解底層機制與高級語言封裝的異同。
typedef struct Node {
int data;
struct Node* next;
} Node;
Node* initList() {
Node* head = (Node*)malloc(sizeof(Node));
if (!head) return NULL;
head->next = NULL;
return head;
}
void insertTail(Node* head, int data) {
if (!head) return;
Node* p = head;
while (p->next) p = p->next; // 找到尾節點
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) return;
newNode->data = data;
newNode->next = NULL;
p->next = newNode;
}
void deleteNode(Node* head, int data) {
if (!head) return;
Node *prev = head, *curr = head->next;
while (curr) {
if (curr->data == data) {
prev->next = curr->next; // 斷鏈
free(curr); // 釋放內存
curr = prev->next; // 繼續遍歷
} else {
prev = curr;
curr = curr->next;
}
}
}
class Node {
int data;
Node next;
public Node(int d) { data = d; }
// 尾插法
void appendToTail(int d) {
Node end = new Node(d);
Node n = this;
while (n.next != null) n = n.next;
n.next = end;
}
}
Node deleteNode(Node head, int d) {
if (head == null) return null;
if (head.data == d) return head.next; // 刪除頭節點
Node n = head;
while (n.next != null) {
if (n.next.data == d) {
n.next = n.next.next; // 斷鏈,GC 自動回收被斷開節點
return head;
}
n = n.next;
}
return head; // 未找到
}
| 維度 | C 語言 | Java |
|---|---|---|
| 內存管理 | 手動 malloc/free,易漏內存/野指針 | 自動 GC,無需釋放 |
| 指針/引用 | 顯式指針操作,靈活但危險 | 引用語義,安全但間接 |
| 頭節點處理 | 需雙指針或傳指針的指針修改頭 | 返回新頭節點引用 |
| 代碼冗長度 | 較長,含錯誤檢查 | 簡潔,異常自動拋出 |
| 適用場景 | 嵌入式、系統級、性能極致敏感 | 應用層開發、業務邏輯為主 |
LinkedList 底層即雙向鏈表,C 需自行維護 prev 指針。理解 C 手動鏈表有助於掌握指針、內存佈局等底層本質;掌握 Java 封裝則能高效完成業務開發。建議初學者先用 C 寫透「增刪改查」,再轉 Java 體會語言賦能,最終查看 JDK LinkedList 源碼,融會貫通。