鏈表是C語言中實現動態數據結構的核心基礎。本文提供一個完整的單向鏈表教學級實現,包含節點定義、創建、遍歷、查找、修改、刪除、尾部插入等核心操作,並構建了交互式菜單系統演示所有功能。代碼雖屬初學者作品,但邏輯完整,極適合理解指針操作與動態內存管理。
struct Student {
int a; // 數據域1
int b; // 數據域2
struct Student* next; // 指針域
};
struct Student* head = NULL; // 全局頭指針
int nodeCount = 0; // 節點計數器
void AddNodes() {
printf("請輸入要存儲的兩個整數(輸入0 0結束)\n");
struct Student *p1, *p2;
p1 = p2 = (struct Student*)malloc(sizeof(struct Student));
head->next = p1;
scanf("%d %d", &p2->a, &p2->b);
while (p2->a != 0) { // 以a==0作為結束標記
nodeCount++;
p1->next = p2;
p1 = p2;
p2 = (struct Student*)malloc(sizeof(struct Student));
scanf("%d %d", &p2->a, &p2->b);
}
p1->next = NULL; // 尾節點指向NULL
}
注意:原代碼使用 scanf_s(MSVC專用),本文統一改為標準 scanf;結束條件 p2->a != NULL 邏輯有誤,已修正為 != 0。
void PrintList(struct Student* head) {
if (head->next == NULL) {
printf("鏈表為空!\n");
return;
}
struct Student* p = head->next;
while (p != NULL) {
printf("%d\t%d\n", p->a, p->b);
p = p->next;
}
}
void FindNode() {
if (head->next == NULL) { printf("鏈表為空!\n"); return; }
int pos; printf("請輸入查找位置(1-%d): ", nodeCount); scanf("%d", &pos);
if (pos < 1 || pos > nodeCount) { printf("位置無效!\n"); return; }
struct Student* p = head->next;
for (int i = 1; i < pos; i++) p = p->next;
printf("第%d個節點: %d\t%d\n", pos, p->a, p->b);
}
void ModifyNode() {
if (head->next == NULL) { printf("鏈表為空!\n"); return; }
int pos; printf("請輸入修改位置(1-%d): ", nodeCount); scanf("%d", &pos);
if (pos < 1 || pos > nodeCount) { printf("位置無效!\n"); return; }
struct Student* p = head->next;
for (int i = 1; i < pos; i++) p = p->next;
printf("請輸入新的兩個整數: "); scanf("%d %d", &p->a, &p->b);
}
void DeleteNode() {
if (head->next == NULL) { printf("鏈表為空!\n"); return; }
int pos; printf("請輸入刪除位置(1-%d): ", nodeCount); scanf("%d", &pos);
if (pos < 1 || pos > nodeCount) { printf("位置無效!\n"); return; }
struct Student* p = head; // 從頭節點開始,方便找到前驅
for (int i = 1; i < pos; i++) p = p->next;
struct Student* del = p->next;
p->next = del->next;
free(del);
nodeCount--;
}
void AppendNodes() {
if (head->next == NULL) { printf("鏈表為空!\n"); return; }
// 先遍歷到尾部
struct Student* p = head->next;
while (p->next != NULL) p = p->next;
printf("請輸入要追加的數據(輸入0 0結束)\n");
struct Student *p2, *p3;
p2 = p3 = (struct Student*)malloc(sizeof(struct Student));
p->next = p2;
scanf("%d %d", &p3->a, &p3->b);
while (p3->a != 0) {
nodeCount++;
p2->next = p3;
p2 = p3;
p3 = (struct Student*)malloc(sizeof(struct Student));
scanf("%d %d", &p3->a, &p3->b);
}
p2->next = NULL;
}
int main() {
head = (struct Student*)malloc(sizeof(struct Student));
head->next = NULL;
nodeCount = 0;
printf("=== 單向鏈表操作演示系統 ===\n");
printf("1. 創建鏈表 2. 遍歷顯示 3. 尾部追加\n");
printf("4. 刪除節點 5. 修改節點 6. 查找節點\n");
printf("0. 退出程序\n");
int choice;
while (1) {
printf("\n請選擇功能(0-6): ");
scanf("%d", &choice);
switch (choice) {
case 0: printf("謝謝使用!\n"); return 0;
case 1: AddNodes(); break;
case 2: PrintList(head); break;
case 3: AppendNodes(); break;
case 4: DeleteNode(); break;
case 5: ModifyNode(); break;
case 6: FindNode(); break;
default: printf("無效選項!\n");
}
}
}
p1跟蹤當前節點,p2預分配下一節點,實現鏈式構建malloc 必須對應 free,刪除操作演示了正確釋放scanf 或封裝跨平台輸入函數本文通過完整可運行的代碼,演示了單向鏈表的全生命周期操作。雖代碼風格屬教學初期作品,但涵蓋了指針操作、動態內存、鏈表遍歷修改等C語言核心難點。建議初學者在理解基礎上,嘗試重構為雙向鏈表、帶哨兵節點鏈表或泛型鏈表,進一步鞏固數據結構功底。