`
BlogDown
  • 浏览: 212884 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

单链表的操作C语言版

 
阅读更多
2009年3月24日 13:04 Slyar 发表评论 阅读评论

文章作者:Slyar 文章来源:Slyar Home (www.slyar.com) 转载请注明,谢谢合作。

昨天数据结构课在讲单链表,所以写了一份单链表的操作C语言实现代码。如果代码有什么不完善的地方,还请指出,谢谢。

操作中包括单链表的创建、插入、查找、删除和销毁等。

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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/*
单链表的操作C语言实现
Slyar 2009.3.23
http://www.slyar.com
*/

#include <stdio.h>
#include <stdlib.h>

/* 给 char 类型定义别名 datatype */
typedef char datatype;

/* 定义链表节点类型 */
typedef struct node
{
        datatype data;
        struct node *next;
}linklist;

/* 函数声明部分 */
linklist* CreatList();
linklist* Get(linklist*, int);
linklist* Locate(linklist*, datatype);
void PrintList(linklist*);
void InsertAfter(linklist*, datatype);
void InsertBefore(linklist*, int, datatype);
void DeleteAfter(linklist*);
void Deleter(linklist*, int);
void FreeList(linklist*);

int main()
{
        int pos;
        datatype value;

        /* 测试创建链表函数 */
        printf("请输入一串字符,以 $ 结束/n");
        linklist *head, *p;
        head = CreatList();

        /* 测试打印链表函数 */
        printf("/n打印链表/n");
        PrintList(head);

        /* 测试按序号查找函数 */
        printf("/n请输入要查找的节点序号:/n");
        scanf("%d", &pos);
        getchar();
        p = Get(head, pos);
        if(p != NULL)
        {
                printf("%c/n", p -> data);
        }
        else
        {
                printf("Can't Get This Key!/n");
        }

        /* 测试按值查找函数 */
        printf("/n请输入要查找的值:/n");
        scanf("%c", &value);
        p = Locate(head, value);
        if(p != NULL)
        {
                printf("%c/n", p -> data);
        }
        else
        {
                printf("Can't Get This Key!/n");
        }

        /* 测试插入节点函数 */
        printf("/n你想在第几个节点前插入?/n");
        scanf("%d", &pos);
        getchar();
        printf("请输入要插入的值/n");
        scanf("%c", &value);
        InsertBefore(head, pos, value);
        PrintList(head);        

        /* 测试删除节点函数 */
        printf("/n你想删除第几个节点?/n");
        scanf("%d", &pos);
        Deleter(head, pos);
        PrintList(head);

        /* 销毁链表 */
        FreeList(head);

        //system("pause");
        return 0;
}

/* 带头结点后插法创建链表函数 */
linklist* CreatList()
{
        datatype key;
        /* head 为头指针, s 为新节点, r 为尾指针 */
        linklist *head, *s, *r;
        head = (linklist*) malloc(sizeof(linklist));
        r = head;
        key = getchar();
        /* 遇到 $ 就停止创建 */
        while(key != '$')
        {
                s = (linklist*) malloc(sizeof(linklist));
                s -> data = key;
                /* 新节点插入表尾 */
                r -> next = s;
                /* 尾指针指向新的表尾 */
                r = s;
                key = getchar();
        }
        r -> next = NULL;
        /* 返回头指针 */
        return head;
}

/* 打印链表函数 */
void PrintList(linklist* head)
{
        linklist *p;
        p = head -> next;
        while(p != NULL)
        {
                printf("%c", p -> data);
                p = p -> next;
        }
        printf("/n");
}

/* 查找链表中第 i 个节点 */
linklist* Get(linklist* head, int i)
{
        /* j 为扫描计数器 */
        int j = 0;
        linklist *p;
        /* p 指向头节点 */
        p = head;
        /* 到达表尾或序号不合法就退出循环 */
        while((p -> next != NULL) && (j < i))
        {
                p = p -> next;
                j++;
        }
        if (i == j)
        {
                return p;
        }
        else
        {
                return NULL;
        }
}

/* 在链表中查找值 key 并返回所在节点 */
linklist* Locate(linklist* head, datatype key)
{
        linklist *p;
        /* p 指向开始结点 */
        p = head -> next;
        while(p != NULL)
        {
                if(p -> data != key)
                {
                        p = p -> next;
                }
                else
                {
                        break;
                }
        }
        return p;
}

/* 在节点 p 后插入 key */
void InsertAfter(linklist* p, datatype key)
{
        linklist *s;
        s = (linklist*) malloc(sizeof(linklist));
        s -> data = key;
        /* 先将 s 指向后一个节点,再将前一个节点指向 s */
        s -> next = p -> next;
        p -> next = s;
}

/* 将 key 插入链表第 i 个节点之前 */
void InsertBefore(linklist* head, int i, datatype key)
{
        linklist *p;
        int j = i - 1;
        /* 找到第 i-1 个节点 p */
        p = Get(head, j);
        if (p == NULL)
        {
                printf("Insert Error!/n");
        }
        else
        {
                /* 将 key 插入节点 p 之后 */
                InsertAfter(p, key);
        }
}

/* 删除 p 节点的后继节点 */
void DeleteAfter(linklist* p)
{
        linklist *r;
        /* r 指向要删除的节点 */
        r = p -> next;
        /* 将 p 直接与 r 下一个节点链接 */
        p -> next = r -> next;
        /* 释放节点 r */
        free(r);
}

/* 删除链表的第 i 个节点 */
void Deleter(linklist* head, int i)
{
        linklist *p;
        int j = i - 1;
        /* 找到第 i-1 个节点 p */
        p = Get(head, j);
        if ((p != NULL) && (p -> next != NULL))
        {
                /* 删除 p 的后继节点 */
                DeleteAfter(p);
        }
        else
        {
                printf("Delete Error!/n");
        }
}

/* 递归释放单链表 */
void FreeList(linklist* p)
{
        if (p -> next != NULL)
        {
                FreeList(p -> next);
        }
        free(p);
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics