無表頭單向鏈表的動態建立,採用「尾插法」:維護頭指標 head 與尾指標 p2,每次將新節點掛在尾部,再移動尾指標。以輸入「0」作為終止條件。
#include "head.h"
#define LEN sizeof(struct Student)
struct Student *creat() {
struct Student *head, *p1, *p2;
int n = 0;
p1 = p2 = (struct Student *)malloc(LEN);
scanf("%s %f", p1->num, N, &p1->score); // 先讀第一筆資料
head = NULL;
while (strcmp(p1->num, "0") != 0) { // "0" 為終止標記
++n;
if (n == 1) {
head = p1; // 第一個節點成為頭節點
} else {
p2->next = p1; // 尾插:將新節點接在尾部
}
p2 = p1; // 尾指標後移
p1 = (struct Student *)malloc(LEN); // 配置下一個節點記憶體
scanf("%s %f", p1->num, N, &p1->score); // 讀取下一筆資料
}
p2->next = NULL; // 尾節點 next 設為 NULL
return head;
}

head = NULL 必須在迴圈前,否則第一個節點無法正確掛載。p2->next = p1 再 p2 = p1,順序不可顛倒。p1 已配置記憶體但不掛入鏈表,迴圈結束後 p2->next = NULL 封閉鏈表,**切勿誤用 p1**。malloc 配置的 p1 未被使用,實際專案中應 free(p1) 釋放。scanf("%s %f", ...) 中 %s 讀字串(學號),%f 讀浮點數(成績),需確認結構體定義一致。若不要求保持輸入順序,頭插法更簡潔:
while (scanf("%s %f", num, &score), strcmp(num, "0")) {
p1 = (struct Student *)malloc(LEN);
strcpy(p1->num, num);
p1->score = score;
p1->next = head;
head = p1;
}
但頭插法會導致鏈表順序與輸入順序相反,視業務需求選擇。
無表頭單向鏈表動態建立的核心是「頭尾指標協作 + 終止條件判斷 + 記憶體管理」。掌握尾插法邏輯,是處理鏈表題目的基礎功夫。