在《C語言實現單鏈表(不帶頭結點)的基本操作》中,我實現了無頭結點單鏈表的 11 種基本操作。實際開發中,帶頭結點單鏈表因統一了首節點與普通節點的處理邏輯,成為主流選擇。本文將系統實現帶頭結點單鏈表的 11 大核心操作,涵蓋初始化、創建、遍歷、增刪改查等全生命周期管理。
typedef int ElemType;
typedef struct Node {
ElemType element;
struct Node* next;
} Node;
分配頭結點內存,next 置 NULL,標記鏈表為空狀態。
void InitialList(Node** ppNode) {
*ppNode = (Node*)malloc(sizeof(Node));
if (!*ppNode) {
printf("%s: 內存分配失敗\n", __FUNCTION__);
return;
}
(*ppNode)->next = NULL;
printf("%s: 初始化完成\n", __FUNCTION__);
}
連續讀取正整數,遇非正數停止。頭結點不存儲有效數據。
void CreateList(Node* pNode) {
Node *pMove = pNode, *pInsert;
int val;
while (scanf("%d", &val) == 1 && val > 0) {
pInsert = (Node*)malloc(sizeof(Node));
if (!pInsert) break;
pInsert->element = val;
pInsert->next = NULL;
pMove->next = pInsert;
pMove = pInsert;
}
printf("%s: 創建成功\n", __FUNCTION__);
}
void PrintList(Node* pNode) {
Node* pMove = pNode->next; // 跳過頭結點
while (pMove) {
printf("%d ", pMove->element);
pMove = pMove->next;
}
printf("\n%s: 打印完成\n", __FUNCTION__);
}
void ClearList(Node* pNode) {
Node *pMove = pNode->next, *pNext;
while (pMove) {
pNext = pMove->next;
free(pMove);
pMove = pNext;
}
pNode->next = NULL;
printf("%s: 清空完成\n", __FUNCTION__);
}
int SizeList(Node* pNode) {
int len = 0;
for (Node* p = pNode->next; p; p = p->next) len++;
printf("%s: 長度=%d\n", __FUNCTION__, len);
return len;
}
int IsEmptyList(Node* pNode) {
int empty = (pNode->next == NULL);
printf("%s: %s\n", __FUNCTION__, empty ? "空" : "非空");
return empty;
}
int GetElement(Node* pNode, int pos) {
if (pos < 1) return -1;
Node* pMove = pNode->next;
for (int i = 1; pMove && i < pos; i++) pMove = pMove->next;
if (!pMove) return -1;
printf("%s: pos=%d 值=%d\n", __FUNCTION__, pos, pMove->element);
return pMove->element;
}
ElemType* GetElemAddr(Node* pNode, int x) {
for (Node* p = pNode->next; p; p = p->next) {
if (p->element == x) {
printf("%s: 找到 x=%d 地址=%p\n", __FUNCTION__, x, (void*)&p->element);
return &p->element;
}
}
return NULL;
}
Node* ModifyElem(Node* pNode, int pos, int x) {
if (pos < 1) return pNode;
Node* pMove = pNode->next;
for (int i = 1; pMove && i < pos; i++) pMove = pMove->next;
if (!pMove) return pNode;
pMove->element = x;
printf("%s: 修改 pos=%d 為 %d 成功\n", __FUNCTION__, pos, x);
return pNode;
}
Node* InsertHeadList(Node* pNode, int x) {
Node* pInsert = (Node*)malloc(sizeof(Node));
if (!pInsert) return pNode;
pInsert->element = x;
pInsert->next = pNode->next;
pNode->next = pInsert;
printf("%s: 表頭插入 %d 成功\n", __FUNCTION__, x);
return pNode;
}
Node* InsertTailList(Node* pNode, int x) {
Node* pMove = pNode;
while (pMove->next) pMove = pMove->next;
Node* pInsert = (Node*)malloc(sizeof(Node));
if (!pInsert) return pNode;
pInsert->element = x;
pInsert->next = NULL;
pMove->next = pInsert;
printf("%s: 表尾插入 %d 成功\n", __FUNCTION__, x);
return pNode;
}
int main() {
Node* list = NULL;
InitialList(&list);
CreateList(list); // 輸入如:10 20 30 -1
PrintList(list); // 10 20 30
SizeList(list); // 3
IsEmptyList(list); // 非空
GetElement(list, 2); // 20
GetElemAddr(list, 20); // 地址
ModifyElem(list, 2, 111);
PrintList(list); // 10 111 30
InsertHeadList(list, 1234);
PrintList(list); // 1234 10 111 30
InsertTailList(list, 9999);
PrintList(list); // 1234 10 111 30 9999
ClearList(list);
PrintList(list); // (空行)
return 0;
}
這套完整實現展示了帶頭結點單鏈表的標準操作模式,代碼結構清晰、邊界處理完善,適合作為教學參考或項目基礎組件。