当我看了这个例子后http://learn.akae.cn/media/ch26s01.html
感觉很简单没什么特别的(这感觉往往遗漏很多细节)。
例子中用了static 定义了关键字 static link head = NULL;
看到后我就想用非static来重写单链表。
习惯了Erlang的函数编程,在定义C语言中的函数时刻意不用指针去实现,为了进一步理解代码还刻意不用typedef定义变量。可是奋斗了很久也没实现。
不得不用取地址方式,最后也没实现。不得不用指针了,这样就造成了传输指针又返回指针了,对于C 语言这可是多此一举。
创建链表时是从表头插入的
75 struct node * insert(struct node *node, char ch)
76 {
77 struct node *node1 = create_node(ch);
78 node1->next = node;
79 return node1;
80 }
81
82 struct node * create_node(char ch)
83 {
84 struct node *node = malloc(sizeof *node);
85 node->element = ch;
86 node->next = NULL;
87 return node;
88 }
写完创建,又写了个删除但是删除不掉
154 struct node * no_delete_node(struct node *head, char ch)
155 {
156
157 printf("no_delete_node2 head->data=%c\n", ch);
158 struct node *ret = head;
159 struct node *pre = head;
160 for(;pre; pre = pre->next){
161 if(pre->element==ch){
162 pre = pre->next;
163 return ret;
164 }
165 }
166 return ret;
167 }
后来改成 (这代码实在在冗余了)就可以删除了,
关键就是 142 行 head->next = pre ->next->next; 这句代码实现了删除
125 struct node * delete_node(struct node *head, char ch)
126 {
127 printf("delete_node head->element=%c\n", head->element);
128 struct node *ret = head;
129 struct node *pre = head;
130 if(head == NULL){
131 return head;
132 }else{
133 if(head->element == ch){
134 head = head ->next;
135 //ret = head->next;
136 return ret;
137 }
138 while(head->next != 0){
139 if(pre->next-> element == ch){
140 struct node *node = pre->next;
141 free_node(node);
142 head->next = pre ->next->next;
143 printf("found del %c\n", head ->element);
144 }else{
145 printf("notfound del%c\n", head ->element);
146 }
147 pre = head->next;
148 }
149 }
150 return ret;
151 }
152
就可以删除了,
最后改成这样实现
171 struct node * delete_node2(struct node *head, char ch)
172 {
173
174 printf("delete_node2 head->data=%c\n", ch);
175 struct node **pre = &head;
176 for(;*pre; pre = &(*pre)->next){
177 if((*pre)->element==ch){
178 *pre = (*pre)->next;
179 return head;
180 }
181 }
182 return head;
183 }
相比较delete_node2 代码简洁多了,乍看上跟no_delete_node方法差不多,本质上却不同。
no_delete_node2并没有删除节点。delete_node2则利用取地址的方式实现,这正是C语言地址指针的妙处。
刚开始想到在node再加一个属性前驱节点,但这已经不是原先数据结构了。
delete_node2
no_delete_node
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
link3.c
#include <stdio.h>
struct
node{
char
element;
struct
node *next;
};
struct
node * create_node(
char
ch);
void
free_node(
struct
node *node);
struct
node * search_node(
struct
node *node,
char
ch);
struct
node * insert (
struct
node *node,
char
ch);
struct
node * delete_node(
struct
node *node,
char
ch);
struct
node * delete_node2(
struct
node *node,
char
ch);
struct
node * delete_node4(
struct
node *node,
char
ch);
struct
node * no_delete_node(
struct
node *head,
char
ch);
void
destroy(
struct
node *node);
void
traverse(
void
(*visit)(
struct
node *),
struct
node *head);
void
print_item(
struct
node *p);
struct
node * push(
struct
node *node,
char
ch);
struct
node * pop(
struct
node *node);
void
list_link(
struct
node *node);
void
list_link2(
struct
node *node);
void
main(
void
)
{
struct
node *node = create_node(
'a'
);
struct
node *found_node =
malloc
(
sizeof
(*found_node));
struct
node *c_node =
malloc
(
sizeof
(*c_node));
printf
(
"node->element=%c\n"
, node->element);
node = insert(node,
'b'
);
printf
(
"node->element=%c\n"
, node->element);
node = insert(node,
'c'
);
printf
(
"node->element=%c\n"
, node->element);
node = insert(node,
'd'
);
printf
(
"node->element=%c\n"
, node->element);
node = insert(node,
'e'
);
printf
(
"node->element=%c\n"
, node->element);
found_node = search_node(node,
'c'
);
//free_node(found_node);
printf
(
"found_node->element=%c\n"
, found_node->element);
puts
(
"before\n"
);
list_link2(node);
puts
(
"del\n"
);
c_node = delete_node2(node,
'b'
);
//c_node = no_delete_node(node, 'b');
puts
(
"after ret c_node \n"
);
list_link(c_node);
puts
(
"after node \n"
);
list_link(node);
//puts("destroy node \n");
//destroy(node);
//list_link(node);
traverse(print_item, node);
}
void
list_link2(
struct
node *head)
{
while
(head){
printf
(
"%c\n"
, head ->element);
head = head ->next;
}
}
void
list_link(
struct
node *node)
{
printf
(
"%c\n"
, node->element);
struct
node *head = node;
while
(head->next){
head = head ->next;
printf
(
"%c\n"
, head ->element);
}
}
struct
node * insert(
struct
node *node,
char
ch)
{
struct
node *node1 = create_node(ch);
node1->next = node;
return
node1;
}
struct
node * create_node(
char
ch)
{
struct
node *node =
malloc
(
sizeof
*node);
node->element = ch;
node->next = NULL;
return
node;
}
struct
node * search_node(
struct
node *head,
char
ch)
{
struct
node *pre = head;
if
(pre == NULL){
return
NULL;
}
else
{
while
(pre != NULL){
if
(pre -> element == ch){
printf
(
"found pre->element=%c\n"
, pre ->element);
return
pre;
}
pre = pre->next;
}
return
NULL;
}
}
struct
node * delete_node(
struct
node *head,
char
ch)
{
printf
(
"delete_node head->element=%c\n"
, head->element);
struct
node *ret = head;
struct
node *pre = head;
if
(head == NULL){
return
head;
}
else
{
if
(head->element == ch){
head = head ->next;
return
ret;
}
while
(head->next != 0){
if
(pre->next-> element == ch){
struct
node *node = pre->next;
free_node(node);
head->next = pre ->next->next;
printf
(
"found del %c\n"
, head ->element);
}
else
{
printf
(
"notfound del%c\n"
, head ->element);
}
pre = head->next;
}
}
return
ret;
}
struct
node * no_delete_node(
struct
node *head,
char
ch)
{
printf
(
"no_delete_node2 head->data=%c\n"
, ch);
struct
node *ret = head;
struct
node *pre = head;
for
(;pre; pre = pre->next){
if
(pre->element==ch){
pre = pre->next;
return
ret;
}
}
return
ret;
}
struct
node * delete_node2(
struct
node *head,
char
ch)
{
printf
(
"delete_node2 head->data=%c\n"
, ch);
struct
node **pre = &head;
for
(;*pre; pre = &(*pre)->next){
if
((*pre)->element==ch){
*pre = (*pre)->next;
return
head;
}
}
return
head;
}
struct
node * delete_node4(
struct
node *head,
char
ch)
{
printf
(
"delete_node4 head->data=%c\n"
, ch);
struct
node *ret = head;
struct
node *pre = head;
while
(NULL != pre->next)
{
if
(pre->next->element == ch)
{
printf
(
"found del %c\n"
, pre->next->element);
pre->next = pre ->next->next;
}
else
pre = pre->next;
}
return
ret;
}
void
free_node(
struct
node *node)
{
free
(node);
}
void
destroy(
struct
node *head)
{
struct
node *del = head;
while
(head){
del = head;
head = head-> next;
free_node(del);
}
}
void
traverse(
void
(*visit)(
struct
node *),
struct
node *head)
{
puts
(
"traverse \n"
);
while
(head){
printf
(
"traverse %c\n"
, head->element);
head = head->next;
}
}
void
print_item(
struct
node *p)
{
printf
(
"%c\n"
, p->element);
}
struct
node * push(
struct
node *node,
char
ch)
{
return
insert(node, ch);
}
struct
node * pop(
struct
node *head)
{
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
link2.c
#include <stdio.h>
struct
node{
char
element;
struct
node *next;
};
struct
node * create_node(
char
ch);
struct
node * delete_node(
struct
node *node,
char
ch);
struct
node * delete_node4(
struct
node *node,
char
ch);
struct
node * search_node(
struct
node *node,
char
ch);
struct
node * insert (
struct
node *node,
char
ch);
void
list_link(
struct
node *node);
void
main(
void
)
{
struct
node *c_node =
malloc
(
sizeof
(*c_node));
struct
node *node = create_node(
'a'
);
struct
node *node2 = node;
printf
(
"node->element=%c\n"
, node->element);
node = insert(node,
'b'
);
printf
(
"node->element=%c\n"
, node->element);
node = insert(node,
'c'
);
printf
(
"node->element=%c\n"
, node->element);
node = insert(node,
'd'
);
printf
(
"node->element=%c\n"
, node->element);
node = insert(node,
'e'
);
//found_node = search_node(node, 'b');
//printf("found_node->element=%c\n", found_node->element);
puts
(
"before\n"
);
list_link(node);
puts
(
"del\n"
);
c_node = delete_node4(node,
'b'
);
puts
(
"after c_node\n"
);
list_link(c_node);
puts
(
"after list node\n"
);
list_link(node);
puts
(
"after list node2\n"
);
list_link(node2);
//printf("%d\n", node.next);
}
void
list_link(
struct
node *node)
{
printf
(
"%c\n"
, node->element);
struct
node *head = node;
while
(head->next != 0){
head = head ->next;
printf
(
"%c\n"
, head ->element);
}
}
struct
node * insert(
struct
node *head,
char
ch)
{
struct
node *node1 = create_node(ch);
node1->next = head;
return
node1;
}
struct
node * create_node(
char
ch)
{
struct
node *head = (
struct
node *)
malloc
(
sizeof
(
struct
node));
head->element = ch;
head->next = NULL;
return
head;
}
struct
node * search_node(
struct
node *head,
char
ch)
{
struct
node *pre = head;
if
(pre == NULL){
return
NULL;
}
else
{
while
(pre != NULL){
if
(pre -> element == ch){
printf
(
"found pre->element=%c\n"
, pre ->element);
return
pre;
}
pre = pre->next;
}
return
NULL;
}
}
struct
node * delete_node(
struct
node *head,
char
ch)
{
printf
(
"delete_node head->element=%c\n"
, head->element);
struct
node *ret = head;
struct
node *pre = head;
if
(pre == NULL){
return
ret;
}
else
{
if
(pre->element == ch){
pre = pre ->next;
return
ret;
}
while
(pre->next != NULL){
printf
(
"----- %c\n"
, pre ->element);
if
(pre->next-> element == ch){
printf
(
"found del %c\n"
, pre ->element);
struct
node *del = pre->next;
free
(del);
pre->next = pre ->next->next;
}
else
{
printf
(
"notfound del%c\n"
, pre ->element);
}
pre = pre->next;
}
}
return
ret;
}
struct
node * delete_node4(
struct
node *head,
char
ch)
{
printf
(
"delete_node4 head->data=%d\n"
, ch);
struct
node *ret = head;
struct
node *pre = head;
while
(NULL != pre->next)
{
if
(pre->next->element == ch)
{
printf
(
"found del %d\n"
, pre->next->element);
pre->next = pre ->next->next;
}
else
pre = pre->next;
}
return
ret;
}
|