Skip to content

Commit edf7254

Browse files
committed
update linkedlist.h
1 parent cc6e888 commit edf7254

File tree

7 files changed

+130
-136
lines changed

7 files changed

+130
-136
lines changed

Linked-List/01-基礎格式.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@ int main() {
4242
append(&first, &trail, "HAT");
4343
linkedListPrintLn(first);
4444

45+
// OUTPUT: BAT -> CAT -> EAT -> FAT -> HAT -> NULL
4546
return 0;
4647
}

Linked-List/02-自訂lib說明.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
1-
/*
2-
本範例利用大量 C 語言技巧
3-
初學者僅需了解 lib/linklist.h 的用法即可 (相信大家能用其他方式實作出來)
4-
本範例是為了提供以後範例能更簡單使用 Linked list 所編
5-
*/
6-
71
#include <stdio.h>
82
#include <stdlib.h>
93
#include "lib/linkedlist.h"
4+
105
/*
116
LinkedList
127
Node* first: 指向串列開頭
138
Node* last: 指向串列結尾
14-
Node append(LinkedList his, void* data): 加入新節點(並返回節點位置)
9+
Node append(LinkedList* this, void* data): 加入新節點(並返回節點位置)
1510
1611
Node
1712
void* data: 節點內容(泛型指標)
1813
Node* next: 指向下一個結點
1914
20-
LinkedList __LinkedList__() 創建新的鍵結串列
15+
__LinkedList__() 創建新的鍵結串列
2116
*/
17+
18+
2219
int main() {
23-
// 宣告新的 LinkedList
24-
LinkedList l = __LinkedList__();
20+
// 透過自訂 lib 來宣告新的 LinkedList
21+
LinkedList* l = __LinkedList__();
2522

2623
// 在 LinkedList l 中依序加入 BAT, CAT, EAT, FAT, HAT
2724
l->append(l, "BAT");
@@ -31,7 +28,7 @@ int main() {
3128
l->append(l, "HAT");
3229

3330
// 結構體 LinkedList 中 first 指向 BAT, last 指向 HAT
34-
Node current;
31+
Node* current;
3532
for (current = l->first; current; current = current->next) {
3633
printf("%s -> ", (char*)(current->data));
3734
}

Linked-List/03-insert.c

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
#include <stdlib.h>
44
#include "lib/linkedlist.h"
55

6-
void insert(LinkedList l, Node insertAfterHere, char* insertThis) {
6+
void insert(LinkedList* l, Node* insertAfterHere, char* insertThis) {
77
// 檢查該佇列是否為空
88
// 該佇列不為空
99
if (l->first) {
10-
Node newNode = malloc(sizeof(*newNode));
10+
Node* newNode = malloc(sizeof(Node));
1111
newNode->data = (void*)insertThis;
1212
newNode->next = insertAfterHere->next;
1313
insertAfterHere->next = newNode;
@@ -18,39 +18,37 @@ void insert(LinkedList l, Node insertAfterHere, char* insertThis) {
1818
}
1919
}
2020

21-
int main() {
22-
LinkedList l = __LinkedList__();
23-
24-
Node BAT = l->append(l, "BAT");
25-
Node CAT = l->append(l, "CAT");
26-
Node EAT = l->append(l, "EAT");
27-
Node FAT = l->append(l, "FAT");
28-
Node HAT = l->append(l, "HAT");
29-
30-
// 原先的串列
31-
Node current;
21+
void printList(LinkedList* l) {
22+
Node* current;
3223
for (current = l->first; current; current = current->next) {
3324
printf("%s -> ", (char*)(current->data));
3425
}
35-
printf("NULL\n\n");
26+
printf("NULL\n");
27+
}
3628

37-
// 在該串列的 CAT 與 EAT 中插入 DAT
38-
insert(l, CAT, "DAT");
29+
int main() {
30+
LinkedList* l = __LinkedList__();
3931

40-
for (current = l->first; current; current = current->next) {
41-
printf("%s -> ", (char*)(current->data));
42-
}
43-
printf("NULL\n\n");
32+
Node* BAT = l->append(l, "BAT");
33+
Node* CAT = l->append(l, "CAT");
34+
Node* EAT = l->append(l, "EAT");
35+
Node* FAT = l->append(l, "FAT");
36+
Node* HAT = l->append(l, "HAT");
4437

45-
// 新建空串列
46-
// 空串列使用 insert 的效果
47-
LinkedList m = __LinkedList__();
48-
insert(m, NULL, "DAT");
38+
// (1) 原先的串列
39+
printList(l);
40+
// OUTPUT: BAT -> CAT -> EAT -> FAT -> HAT -> NULL
4941

50-
for (current = m->first; current; current = current->next) {
51-
printf("%s -> ", (char*)(current->data));
52-
}
53-
printf("NULL");
42+
// (2) 在該串列的 CAT 與 EAT 中插入 DAT
43+
insert(l, CAT, "DAT");
44+
printList(l);
45+
// OUTPUT: BAT -> CAT -> DAT -> EAT -> FAT -> HAT -> NULL
46+
47+
// (3) 新建空串列,空串列使用 insert 的效果
48+
LinkedList* m = __LinkedList__();
49+
insert(m, NULL, "DAT");
50+
printList(m);
51+
// OUTPUT: DAT -> NULL
5452

5553
return 0;
5654
}

Linked-List/04-delete.c

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,54 +3,53 @@
33
#include <stdlib.h>
44
#include "lib/linkedlist.h"
55

6-
void delete (LinkedList l, Node nodeBeforeTarget) {
6+
void delete (LinkedList* l, Node* nodeBeforeTarget) {
77
// nodeBeforeTarget 為 NULL 代表刪除第一個節點
88
// nodeBeforeTarget 有值代表刪除的不是第一個節點
99
if (nodeBeforeTarget) {
10-
Node target = nodeBeforeTarget->next;
11-
Node nodeAfterTarget = target->next;
10+
Node* target = nodeBeforeTarget->next;
11+
Node* nodeAfterTarget = target->next;
1212
free(target);
1313
nodeBeforeTarget->next = nodeAfterTarget;
1414
} else {
15-
Node target = l->first;
16-
Node nodeAfterTarget = target->next;
15+
Node* target = l->first;
16+
Node* nodeAfterTarget = target->next;
1717
free(target);
1818
l->first = nodeAfterTarget;
1919
}
2020
}
2121

22-
int main() {
23-
LinkedList l = __LinkedList__();
24-
25-
Node BAT = l->append(l, "BAT");
26-
Node CAT = l->append(l, "CAT");
27-
Node EAT = l->append(l, "EAT");
28-
Node FAT = l->append(l, "FAT");
29-
Node HAT = l->append(l, "HAT");
30-
31-
// 原先的串列
32-
Node current;
22+
void printList(LinkedList* l) {
23+
Node* current;
3324
for (current = l->first; current; current = current->next) {
3425
printf("%s -> ", (char*)(current->data));
3526
}
36-
printf("NULL\n\n");
27+
printf("NULL\n");
28+
}
3729

38-
// 試刪除 CAT 後的 EAT
39-
delete (l, CAT);
30+
int main() {
31+
LinkedList* l = __LinkedList__();
4032

41-
for (current = l->first; current; current = current->next) {
42-
printf("%s -> ", (char*)(current->data));
43-
}
44-
printf("NULL\n\n");
33+
Node* BAT = l->append(l, "BAT");
34+
Node* CAT = l->append(l, "CAT");
35+
Node* EAT = l->append(l, "EAT");
36+
Node* FAT = l->append(l, "FAT");
37+
Node* HAT = l->append(l, "HAT");
38+
39+
// (1) 原先的串列
40+
printList(l);
41+
// OUTPUT: BAT -> CAT -> EAT -> FAT -> HAT -> NULL
42+
43+
// (2) 試刪除 CAT 後的 EAT
44+
delete (l, CAT);
45+
printList(l);
46+
// OUTPUT: BAT -> CAT -> FAT -> HAT -> NULL
4547

46-
// 試刪除頭結點 BAT
48+
// (3) 試刪除頭結點 BAT
4749
// 因為 BAT 前沒有節點所以我們用 NULL 來代替 nodeBeforeTarget
4850
delete (l, NULL);
49-
50-
for (current = l->first; current; current = current->next) {
51-
printf("%s -> ", (char*)(current->data));
52-
}
53-
printf("NULL\n\n");
51+
printList(l);
52+
// OUTPUT: CAT -> FAT -> HAT -> NULL
5453

5554
return 0;
5655
}

Linked-List/05-invert.c

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
#include <stdlib.h>
44
#include "lib/linkedlist.h"
55

6-
LinkedList invert(LinkedList l) {
6+
LinkedList* invert(LinkedList* l) {
77
/*
88
比較好懂的作法
99
10-
Node newList, current, next;
10+
Node* newList;
11+
Node* current;
12+
Node* next;
1113
newList = NULL;
1214
for(current = l->first; current; current=next){
1315
// 暫時存著下一個 current 的位址
@@ -18,16 +20,17 @@ LinkedList invert(LinkedList l) {
1820
newList = current;
1921
}
2022
21-
LinkedList m = __LinkedList__();
23+
LinkedList* m = __LinkedList__();
2224
m->first = newList;
2325
m->last = l->first;
2426
2527
return m;
2628
*/
2729

2830
// 課本作法
29-
Node trail, middle;
30-
Node lead = l->first;
31+
Node* trail;
32+
Node* middle;
33+
Node* lead = l->first;
3134
middle = NULL;
3235
while (lead) {
3336
trail = middle;
@@ -36,8 +39,7 @@ LinkedList invert(LinkedList l) {
3639
middle->next = trail;
3740
}
3841

39-
// 因為我用的是 OOP 所以又多的幾步 (記錄新串列開頭而已也沒什麼)
40-
LinkedList m = __LinkedList__();
42+
LinkedList* m = __LinkedList__();
4143
m->first = middle;
4244
m->last = l->first;
4345

@@ -50,14 +52,13 @@ LinkedList invert(LinkedList l) {
5052
lead: 走訪原本的 linked list
5153
5254
while(lead){
53-
trail = middle; // [STEP2] trail 暫存 middle
54-
(保持在新串列的最前端) middle = lead; // [STEP3] middle 暫存
55-
lead lead = lead->next; // [STEP4] lead 走訪舊串列 middle->next =
56-
trail // [STEP1] 將走訪到的舊串列節點加回新串列 (從前方加入(stack
57-
push))
55+
trail = middle; // trail 暫存 middle
56+
middle = lead; // middle 暫存 lead
57+
lead = lead->next; // 每次迭代時 lead 走訪原串列的下個節點
58+
middle->next = trail // 將走訪到的原串列節點加回新串列
5859
}
5960
60-
課本上的作法實在過於精簡,只有神人才看得懂吧
61+
課本上的作法非常精簡
6162
Fundamentals of Data Structure in C p.171 Program 4.16
6263
6364
自己實作上建議可以將想法想成
@@ -67,27 +68,30 @@ LinkedList invert(LinkedList l) {
6768
*/
6869
}
6970

71+
void printList(LinkedList* l) {
72+
Node* current;
73+
for (current = l->first; current; current = current->next) {
74+
printf("%s -> ", (char*)(current->data));
75+
}
76+
printf("NULL\n");
77+
}
78+
7079
int main() {
71-
LinkedList l = __LinkedList__();
80+
LinkedList* l = __LinkedList__();
7281
l->append(l, "BAT");
7382
l->append(l, "CAT");
7483
l->append(l, "EAT");
7584
l->append(l, "FAT");
7685
l->append(l, "HAT");
7786

78-
printf("l: \t");
79-
Node current;
80-
for (current = l->first; current; current = current->next) {
81-
printf("%s -> ", (char*)(current->data));
82-
}
83-
printf("NULL\n");
87+
printf("original: \t");
88+
printList(l);
89+
// OUTPUT: BAT -> CAT -> EAT -> FAT -> HAT -> NULL
8490

85-
LinkedList m = invert(l);
91+
LinkedList* m = invert(l);
92+
printf("inverted: \t");
93+
printList(m);
94+
// OUTPUT: HAT -> FAT -> EAT -> CAT -> BAT -> NULL
8695

87-
printf("m: \t");
88-
for (current = m->first; current; current = current->next) {
89-
printf("%s -> ", (char*)(current->data));
90-
}
91-
printf("NULL\n");
9296
return 0;
9397
}

0 commit comments

Comments
 (0)