数据结构 --- 线性表(单链表)

工程目录结构:

common.h:

 1 //#ifndef __common_h__
 2 //#define __common_h__
 3 
 4 #define OK 1
 5 #define ERROR 0
 6 #define TRUE 1
 7 #define FALSE 0 
 8 
 9 #define MAXSIZE 20
10 
11 typedef int Status;        //函数的返回结果,OK、ERREO、TRUE、FALSE
12 typedef int ElemType;   //结点数据域的数据类型
13 
14 //#endif

common.c:

1 #include "common.h"
2 
3 Status visit(ElemType e)
4 {
5     printf("%d , ", e);
6     return OK;
7 }

LinkList.h:

1 //单链表结点定义
2 typedef struct Node
3 {
4     ElemType data;
5     struct  Node *next;
6 }Node;
7 
8 typedef  struct  Node *LinkList;  //单链表定义

LinkList.c:

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 #include <math.h>  
  4 #include <time.h>
  5 #include <stdlib.h>
  6 
  7 //注意以下两个 .h 的包含顺序
  8 #include "common.h"
  9 #include "LinkList.h"
 10 
 11 //初始化单链表
 12 Status InitLinkList(LinkList *L)
 13 {
 14     *L = (LinkList)malloc(sizeof(Node));    //生成头结点,并式指针指向它
 15     if (*L == NULL)                            //头结点生成失败
 16     {
 17         return ERROR;
 18     }
 19 
 20     (*L)->next = NULL;
 21     return OK;
 22 }
 23 
 24 //计算单链表的长度, 该单链表带有头结点
 25 int ListLength(LinkList L)
 26 {
 27     int count = 0;
 28 
 29     if (NULL != L)
 30     {
 31         LinkList p = L->next;
 32         while (NULL != p)
 33         {
 34             ++count;
 35             p = p->next;
 36         }
 37     }
 38 
 39     return count;
 40 }
 41 
 42 
 43 
 44 //在L的第i个位置插入元素e
 45 Status ListInsert(LinkList *L, int i, ElemType e)
 46 {
 47     LinkList p = *L;
 48     int index = 1;
 49     //查找第i个结点
 50     while (p && index < i)
 51     {
 52         p = p->next;
 53         ++index;
 54     }
 55 
 56     //第一个元素不存在
 57     if (!p && index > i)
 58     {
 59         return ERROR;
 60     }
 61 
 62     //生成新结点
 63     LinkList s = (LinkList)malloc(sizeof(Node));
 64     s->next = p->next;
 65     s->data = e;
 66     p->next = s;
 67     return OK;
 68 }
 69 
 70 //输出单链表的元素
 71 Status ListTraverse(LinkList L)
 72 {
 73     if (NULL != L)
 74     {
 75         LinkList p = L->next;
 76         while (NULL != p)
 77         {
 78             visit(p->data);
 79             p = p->next;
 80         }
 81         return OK;
 82     }
 83     return FALSE;
 84 }
 85 
 86 //判断单链表是否为空链表
 87 Status ListEmpty(LinkList L)
 88 {
 89     if (NULL != L)
 90     {
 91         if (NULL == L->next)
 92         {
 93             return TRUE;
 94         }
 95         else
 96         {
 97             return FALSE;
 98         }
 99     }
100     else
101     {
102         printf("单链表未初始化\n\n");
103         return TRUE;
104     }
105 }
106 
107 
108 
109 //清除单链表数据,置为空
110 Status ListClear(LinkList *L)
111 {
112     if (NULL != L)
113     {
114         LinkList p, q;
115         p = (*L)->next;
116         while (p)
117         {
118             q = p->next;
119             free(p);
120             p = q;
121         }
122 
123         (*L)->next = NULL;   //置空头结点指针域
124         return TRUE;
125     }
126 
127     return FALSE;
128 }
129 
130 //返回第i个元素,e来保存
131 Status GetElem(LinkList L, int i, ElemType *e)
132 {
133     if (NULL != L)
134     {
135         int index = 1;
136         LinkList p = L->next;
137         while (NULL != p && index < i)
138         {
139             ++index;
140             p = p->next;
141         }
142 
143         //第i个元素不存在
144         if (NULL != p && index > i)
145         {
146             return ERROR;
147         }
148 
149         *e = p->data;
150         return OK;
151     }
152     return FALSE;
153 }
154 
155 //返回第一个值为e的位序(1开始)
156 int LocateElem(LinkList L, ElemType e)
157 {
158     if (NULL != L)
159     {
160         int index = 0;
161         LinkList p = L->next;
162         while (NULL != p)
163         {
164             ++index;
165             if (e == p->data)
166             {
167                 return index;
168             }
169             p = p->next;
170         }
171     }
172     return 0;
173 }
174 
175 //删除第 i 个位置的元素,e保存删除的元素
176 Status ListDelete(LinkList *L, int i, ElemType *e)
177 {
178     if (NULL != (*L))
179     {
180         LinkList p = *L;
181         int index = 1;
182         while (NULL != p->next && index < i)
183         {
184             ++index;
185             p = p->next;
186         }
187 
188         while (!(p->next) || index > i)
189         {
190             return ERROR;
191         }
192 
193         LinkList q = p->next;
194         p->next = q->next;
195         *e = q->data;
196         free(q);
197         return OK;
198     }
199     return ERROR;
200 }
201 
202 //随机产生n个元素的值,建立带表头结点的单链线性表L(头插法)
203 void CreateListHead(LinkList *L, int n)
204 {
205     srand(time(0));   //初始化随机数种子
206     LinkList p;
207     *L = (LinkList)malloc(sizeof(Node));
208     (*L)->next = NULL;
209     for (int i = 0; i < n; ++i)
210     {
211         p = (LinkList)malloc(sizeof(Node));
212         p->data = rand() % 100 + 1;    //随机生成100以内的数字
213         p->next = (*L)->next;
214         (*L)->next = p;                    //插到表头
215     }
216 }
217 
218 //随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法)
219 void CreateListTrail(LinkList *L, int n)
220 {
221     srand(time(0));   //初始化随机数种子
222     LinkList p,r;
223     *L = (LinkList)malloc(sizeof(Node));
224     r = *L;            //r为指向尾部的结点
225     for (int i = 0; i < n; ++i)
226     {
227         p = (LinkList)malloc(sizeof(Node));
228         p->data = rand() % 100 + 1;        //随机生成100以内的数字
229         r->next = p;                    //将表尾终端结点的指针指向新结点
230         r = p;                            //将当前的新结点定义为表尾终端结点
231     }
232     r->next = NULL;  //链表结束
233 }
234 
235 //单链表测试的入口
236 void LinkListStart()
237 {
238     printf("\n######## 单链表 测试 Start ############\n");
239 
240     LinkList L = NULL;
241     printf("单链表初始化结果: %d\n\n", InitLinkList(&L));
242     printf("初始化后,单链表的长度是: %d\n\n", ListLength(L));
243     printf("插入元素 1 - 10 \n");
244     for (int i = 1; i <= 10; ++i)
245         ListInsert(&L, i, i);
246     printf("插入的元素分别是: ");
247     ListTraverse(L);
248 
249     printf("\n\n单链表是否为空: %d\n", ListEmpty(L));
250     printf("\n\n单链表的长度是: %d\n", ListLength(L));
251 
252     if (OK == ListClear(&L))
253     {
254         printf("\n单链表置空\n");
255         printf("单链表是否为空: %d\n", ListEmpty(L));
256         printf("单链表的长度是: %d\n", ListLength(L));
257     }
258 
259     printf("\n\n\n插入元素 1 - 5 \n");
260     for (int i = 1; i <= 5; ++i)
261         ListInsert(&L, i, i);
262     printf("插入的元素分别是: ");
263     ListTraverse(L);
264     printf("\n单链表的长度是: %d\n", ListLength(L));
265 
266     ListInsert(&L, 1, 0);
267     printf("表头插入0后:\n");
268     ListTraverse(L);
269     printf("\n单链表的长度是: %d\n", ListLength(L));
270 
271     ElemType e;
272     GetElem(L, 3, &e);
273     printf("单链表的第3个元素是: %d\n", e);
274 
275     int k = 0;
276     for (int i = 2; i <= 4; ++i)
277     {
278         k = LocateElem(L, i);
279         if (0 != k)
280         {
281             printf("第 %d 个元素的值为 %d\n", k, i);
282         }
283         else
284         {
285             printf("没有值为 %d 的元素\n", i);
286         }
287     }
288 
289     int index = 3;
290     ListDelete(&L, index, &e);
291     printf("\n删除第%d个的元素值为:%d\n", index, e);
292     printf("依次输出单链表的元素:");
293     ListTraverse(L);
294 
295     ListClear(&L);
296     printf("\n\n清空单链表后的长度:%d\n", ListLength(L));
297 
298     CreateListHead(&L, 6);
299     printf("\n创建单链表元素(头插法):\n");
300     ListTraverse(L);
301     ListClear(&L);
302 
303 
304     CreateListTrail(&L, 6);
305     printf("\n\n创建单链表元素(尾插法):\n");
306     ListTraverse(L);
307     ListClear(&L);
308 
309     printf("\n\n####### 单链表 测试 End ###########");
310 }

main.c:

1 int main()
2 {
3     LinkListStart();
4     //StackStart();
5     //LinkStackStart();
6     getchar();
7     return 0;
8 }
posted @ 2018-06-29 18:13  小·糊涂仙  阅读(209)  评论(0编辑  收藏  举报