关于单链表的思考

当我看了这个例子后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


关于单链表的思考_第1张图片
 

 no_delete_node


关于单链表的思考_第2张图片
 

 

 

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;

 

你可能感兴趣的:(单链表)