typedef struct Node {
int data;
struct Node *next;
} Node;
Node *create(void)
{
const int n = 20; // 固定建立 20 個節點
Node *pNew, *pTail, *pHead;
// 1. 建立頭節點,next 指向自己,構成空循環表
pHead = (Node *)malloc(sizeof(Node));
if (!pHead) { perror("malloc head"); exit(EXIT_FAILURE); }
pHead->next = pHead;
pTail = pHead; // 尾指標初始指向頭節點
// 2. 尾插法建立 20 個節點,data 為 1..20
for (int i = 1; i <= n; i++) {
pNew = (Node *)malloc(sizeof(Node));
if (!pNew) { perror("malloc node"); exit(EXIT_FAILURE); }
pNew->data = i;
if (pHead->next == pHead) { // 空表:第一個節點
pHead->next = pNew;
pTail = pNew;
} else { // 非空表:接在尾部
pTail->next = pNew;
pTail = pNew;
}
}
// 3. 閉合循環:尾節點 next 指向頭節點
pTail->next = pHead;
return pTail; // 回傳尾節點(亦可回傳 pHead)
}
head->next == head,判斷空表極簡單。if 分支,純尾插法可完全統一)。pTail 指向最後一個資料節點,尾插時間複雜度 O(1)。pTail = pNew。建立完成後必須執行 pTail->next = pHead,使最後一個節點指回頭節點,形成完整循環。
pTail:便於後續尾插操作(直接用尾指標)。pHead:便於遍歷、搜尋等從頭開始的操作。void print_list(Node *head)
{
Node *cur = head->next;
while (cur != head) {
printf("%d ", cur->data);
cur = cur->next;
}
putchar('\n');
}
void free_list(Node *head)
{
Node *cur = head->next;
while (cur != head) {
Node *tmp = cur;
cur = cur->next;
free(tmp);
}
free(head);
}
n 參數化,而非硬編碼。exit(),提高函式復用性。calloc 自動歸零指標欄位。