typedef int Item;
typedef struct Node {
Item data;
struct Node *prev;
struct Node *next;
} Node, *PNode, *Position;
typedef struct {
PNode head; // 虛擬頭節點
PNode tail; // 指向尾節點
int size; // 節點數
} DList;
採用帶虛擬頭節點的雙向鏈表,簡化邊界條件處理。
| 分類 | 函數 |
|---|---|
| 節點管理 | MakeNode, FreeNode |
| 鏈表生命週期 | InitList, DestroyList, ClearList |
| 查詢 | GetHead, GetTail, GetSize, GetNext, GetPrevious, GetItem, SetItem, LocatePos |
| 插入 | InsFirst, InsBefore, InsAfter |
| 刪除 | DelFirst, Remove |
| 遍歷 | ListTraverse(配合訪問者回調) |
DList *InitList() {
DList *list = malloc(sizeof(DList));
PNode head = MakeNode(0); // data 無意義
list->head = list->tail = head;
list->size = 0;
return list;
}
PNode InsFirst(DList *list, PNode node) {
node->next = list->head->next;
node->prev = list->head;
if (list->head->next) list->head->next->prev = node;
list->head->next = node;
if (list->tail == list->head) list->tail = node; // 空表情況
list->size++;
return node;
}
PNode Remove(DList *list) {
if (list->size == 0) return NULL;
PNode node = list->tail;
node->prev->next = node->next; // node->next 為 NULL
list->tail = node->prev;
list->size--;
return node; // 呼叫者負責 FreeNode
}
PNode InsBefore(DList *list, Position pos, PNode node) {
node->prev = pos->prev;
node->next = pos;
pos->prev->next = node;
pos->prev = node;
list->size++;
return node;
}
PNode LocatePos(DList *list, int i) {
if (i < 1 || i > list->size) return NULL;
PNode p = list->head;
while (i--) p = p->next;
return p;
}
void ListTraverse(DList *list, void (*visit)(Item)) {
for (PNode p = list->head->next; p; p = p->next)
visit(p->data);
}
InitList() 建立空表n 及各節點資料InsFirst 建立首節點,後續 InsAfter 尾部追加ListTraverse 列印驗證DestroyList 釋放所有記憶體MakeNode → malloc,FreeNode → freeClearList 從尾部向前逐個 freeDestroyList 先 ClearList 再 free(head) 最後 free(list)ReverseTraverse 反向列印DeleteByValue(Item val) 刪除首個匹配節點Item 改為 void* 實現泛型容器雙向鏈表透過 prev/next 雙向連結,支援 O(1) 頭尾插刪、雙向遍歷。虛擬頭節點統一邊界邏輯,是教學與工程常用技巧。掌握指標操作、記憶體管理、訪問者模式遍歷,即可靈活應用於各類動態資料集合。