一、头结点
一个不存有效数据的"哨兵结点",头结点的 next 才指向第一个数据结点。
二、区别
1. 空链表表现不同
-
不带头结点 :
head = NULL(直接是空指针) -
带头结点 :
head ≠ NULL,但head->next = NULL(永远有头结点)
2. 插入/删除操作
-
不带头结点
-
在链表头部插入/删除 时,必须修改头指针 head
-
头部操作和中间/尾部操作代码逻辑不一样,要单独判断
-
容易出现空指针、逻辑错误
-
cpp
// 在头部插入新结点
void add(Node** head, int val) {
Node* new = create(val);
if (*head == NULL) { // 必须单独判断空表
*head = new; // 直接修改头指针
} else {
new->next = *head;
*head = new;
}
}
-
带头结点
- 无论在头部、中间、尾部插入/删除,逻辑完全统一
cpp
// 无论空表还是非空,代码都一样
void add(Node* head, int val) {
Node* new = create(val);
new->next = head->next;
head->next = new; // 永远不用修改 head 本身
}