循環鏈表與單鏈表類似,差別在於最後一個節點的 next 指向頭節點而非 NULL。尾插法維護 tail 指針,每次在尾部插入新節點並更新 tail,最後閉環。
typedef struct clist {
int data;
struct clist *next;
} cnode, *clink;
clink create_clist(int *array, int len) {
if (len == 0) return NULL;
clink head = (clink)malloc(sizeof(cnode));
if (!head) return NULL;
head->data = array[0];
head->next = NULL;
clink tail = head;
for (int i = 1; i < len; ++i) {
clink new_node = (clink)malloc(sizeof(cnode));
if (!new_node) return NULL; // 實際應釋放已分配節點
new_node->data = array[i];
new_node->next = NULL;
tail->next = new_node;
tail = new_node;
}
tail->next = head; // 形成環
return head;
}
void print_clist(clink head) {
if (!head) return;
clink p = head;
do {
printf("%d ", p->data);
p = p->next;
} while (p != head);
puts("");
}
void free_clist(clink head) {
if (!head) return;
clink p = head->next;
while (p != head) {
clink tmp = p;
p = p->next;
free(tmp);
}
free(head);
}
int main() {
int arr[] = {9, 7, 3, 4, 5, 6};
clink head = create_clist(arr, 6);
if (!head) { puts("記憶體分配失敗"); return 1; }
print_clist(head); // 輸出:9 7 3 4 5 6
free_clist(head);
return 0;
}
tail 指針,避免每次遍歷到尾部(O(n²) → O(n))。tail->next = head。do-while(p != head) 確保至少執行一次並正確停止。