節點定義
typedef int ElemType;
typedef struct Node {
ElemType data;
struct Node *prev, *next;
} Node;
核心操作函數速查表
| 函數 | 功能 | 關鍵邏輯 |
InitList | 初始化 | 分配頭尾哨兵,head->next=tail, tail->prev=head |
CreateList | 尾插建表 | 輸入>0 循環插入尾哨兵前 |
PrintList | 正序打印 | p=head->next; while(p!=tail) |
PrintReverse | 逆序打印 | p=tail->prev; while(p!=head) |
ClearList | 清空 | 依次 free head->next 直到遇到 tail |
SizeList | 長度 | 遍歷計數 |
IsEmpty | 判空 | head->next == tail |
GetElement | 按位置取值 | 遍歷到 pos 返回 data |
GetElemAddr | 按值找地址 | 遍歷匹配返回 &node->data |
ModifyElem | 修改位置值 | 遍歷到 pos 賦新值 |
InsertHead | 頭插 | 新節點夾在 head 與 head->next 間 |
InsertTail | 尾插 | 新節點夾在 tail->prev 與 tail 間 |
關鍵代碼片段:頭插與尾插
// 頭插
void insertHead(Node *head, Node *tail, int x) {
Node *n = malloc(sizeof(Node));
n->data = x;
n->prev = head;
n->next = head->next;
head->next->prev = n;
head->next = n;
}
// 尾插
void insertTail(Node *head, Node *tail, int x) {
Node *n = malloc(sizeof(Node));
n->data = x;
n->next = tail;
n->prev = tail->prev;
tail->prev->next = n;
tail->prev = n;
}
測試主程序
int main() {
Node *head, *tail;
InitList(&head, &tail);
CreateList(head, tail); // 輸入: 1 2 3 0
PrintList(head, tail); // 1 2 3
PrintReverse(head, tail); // 3 2 1
InsertHead(head, tail, 100);
InsertTail(head, tail, 900);
PrintList(head, tail); // 100 1 2 3 900
ClearList(head, tail);
PrintList(head, tail); // (空行)
return 0;
}
設計優勢總結
- 統一了首尾/中間/空表的操作邏輯,無需特判。
- 雙向鏈接使逆序遍歷、尾部操作同樣高效。
- 哨兵節點簡化邊界條件,代碼健壯性大幅提升。