typedef struct node {
char name[20];
struct node *llink; // 指向前驅節點
struct node *rlink; // 指向後繼節點
} stud;
特徵:
stud *creat(int n) {
stud *p, *h, *s;
int i;
// 配置頭節點
if ((h = (stud *)malloc(sizeof(stud))) == NULL) {
printf("記憶體配置失敗!");
exit(0);
}
h->name[0] = '\0';
h->llink = NULL;
h->rlink = NULL;
p = h;
// 迴圈建立 n 個資料節點
for (i = 0; i < n; i++) {
if ((s = (stud *)malloc(sizeof(stud))) == NULL) {
printf("記憶體配置失敗!");
exit(0);
}
p->rlink = s; // 前一節點後繼指向新節點
printf("請輸入第%d個人的姓名: ", i+1);
scanf("%s", s->name);
s->llink = p; // 新節點前驅指向前一節點
s->rlink = NULL; // 暫時設 NULL
p = s; // 移動 p 到新節點
}
// 完成循環連結
h->llink = p; // 頭節點前驅指向尾節點
p->rlink = h; // 尾節點後繼指向頭節點
return h; // 返回頭節點指標
}
stud *search(stud *h, char *x) {
stud *p;
char *y;
p = h->rlink; // 從第一個資料節點開始
while (p != h) { // 未回到頭節點
y = p->name;
if (strcmp(y, x) == 0) // 找到目標
return p; // 返回節點指標
else
p = p->rlink; // 移向後繼
}
printf("沒有查找到該資料!\n");
return NULL; // 未找到
}
void print(stud *h) {
stud *p;
p = h->rlink;
printf("資料資訊為:\n");
while (p != h) {
printf("%s ", p->name); // 或 &*p->name
p = p->rlink;
}
printf("\n");
}
#include
#include
#include
#define N 10
typedef struct node {
char name[20];
struct node *llink, *rlink;
} stud;
stud *creat(int n);
stud *search(stud *h, char *x);
void print(stud *h);
main() {
int number = N;
char studname[20];
stud *head, *searchpoint;
// clrscr(); // 清螢幕(特定編譯器)
head = creat(number);
print(head);
printf("請輸入你要查找的人的姓名: ");
scanf("%s", studname);
searchpoint = search(head, studname);
if (searchpoint)
printf("你所要查找的人的姓名是: %s\n", searchpoint->name);
}
// 初始:頭節點
h → [name=""][llink=NULL][rlink=NULL]
p = h
// 第 1 節點插入
s → [name="Alice"][llink=h][rlink=NULL]
h->rlink = s; s->llink = h; p = s
// 第 2 節點插入
s → [name="Bob"][llink=Alice][rlink=NULL]
Alice->rlink = s; s->llink = Alice; p = s
// ... 完成 n 節點後
h->llink = 尾節點
尾節點->rlink = h
// 最終結構:
h ↔ 節點1 ↔ 節點2 ↔ ... ↔ 節點n
↑______________________________↓ (循環)
h->rlink(首資料節點)開始p != h(未繞回頭節點)p->name 與目標 xp;不符 → p = p->rlink 移向下一節點| 操作 | 單向鏈表 | 雙向鏈表 |
|---|---|---|
| 反向遍歷 | 不可(需遞迴/堆疊) | 直接 p = p->llink |
| 刪除指定節點 | 需從頭找前驅 O(n) | 已知節點 O(1) 直接 p->llink->rlink = p->rlink |
| 前驅查詢 | O(n) | O(1) |
| 記憶體開銷 | 1 指標/節點 | 2 指標/節點 |