`
langzhe
  • 浏览: 278549 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于单链表的思考

    博客分类:
  • c
 
阅读更多

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

 

  • 大小: 163.7 KB
  • 大小: 132.1 KB
0
6
分享到:
评论

相关推荐

    单链表之头部插入节点.pdf

    哪几步, 每步做什么, 然后再去思考每步的代码实现是什么, 否则就会只看到指 针指来指去, 很快就晕头转向了。 头插入节点的两个重要步骤: (1) 新节点的 pNext 指向原来的第一个节点的首地址, 即新节点和原来...

    数据结构实验指导书(单链表验证二叉树图的存储)

    数据结构是一门实践性很强的...对于一个实际问题,每个人可能会有不同的解决办法,本书给出的范例方案,只是希望把学生的思路引人正轨,提出了思考问题的方法,但是不希望限制学生的思维,鼓励学生自己设计解决方案。

    数据结构实验

    2.复习关于队列操作的基础知识。 3.编写完整程序完成下面的实验内容并上机运行。 4.整理并上交实验报告。 三、实验内容 1.任意输入队列长度和队列中的元素值,构造一个顺序循环队列,对其进行清空、插入新元素、...

    单向链表基本操作的递归实现

    这几天正在复习一些基本的算法和实现,今天看了看递归...记得高中的时候最喜欢做的题目就是数学归纳方面的证明,现在想过来好多问题我不能采用这种方式思考,可见知识真的是有联系的,只是我们没有找到联系的方式而已。

    《数据结构(c语言版)习题集》算法设计题答案

    说明: 1. 本文是对严蔚敏《数据结构(c语言版)习题集》一书中所有... 由于作者水平所限,本解答中一定存在不少这样或者那样的错误和不足,希望读者们在阅读中多动脑、勤思考,争取发现和纠正这些错误,写出更好的算法来.

    数据结构课程设计航空订票系统.doc

    目录 总体设计 2 概要设计 2 详细设计 3 调试分析 11 测试数据及截图 11 时间复杂度分析 15 问题思考 15 算法的改进设想 15 课设总结体会 15 附录 17 程序说明 17 源代码 17 主要参考文献 30 总体设计 通过此系统...

    LeetCode解题总结

    10.7.2 思考步骤 10.7.3 代码模板 10.7.4 深搜与回溯、递归的区别 11. 分治法 11.1 实现pow(x, n) 11.2 Sqrt(x) 12. 贪心算法 12.1 跳台阶游戏 12.2 买卖股票的最佳时机 12.2.1 最多允许交易一次 12.2.2 可以交易...

    leetcode中国-LeetCode:力扣解决方案

    多次思考可以尝试解决 #代表思路顺畅,可以解决 具体的思路,请看每道题目对应的README 说明 此部分包括Leetcode部分习题 剑指offer的部分习题 左神算法课程的练习 使用C++实现的 已学习到的知识总结 左神算法课 L00...

    计算机二级C语言考试题预测

    (18) 下述关于数据库系统的叙述中正确的是(A) A. 数据库系统减少了数据冗余 B. 数据库系统避免了一切冗余 C. 数据库系统中数据的一致性是指数据类型的一致 D. 数据库系统比文件系统能管理更多的数据 (19) 关系表中的...

    二级C语言公共基础知识

    (18) 下述关于数据库系统的叙述中正确的是______。(A) A. 数据库系统减少了数据冗余 B. 数据库系统避免了一切冗余 C. 数据库系统中数据的一致性是指数据类型的一致 D. 数据库系统比文件系统能管理更多的数据 (19) ...

    用C编写班级成绩管理系统

    通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。...

Global site tag (gtag.js) - Google Analytics