线性表链式存储

Posted baidaye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表链式存储相关的知识,希望对你有一定的参考价值。

  1 #include "stdio.h"
  2 #include "string.h"
  3 #include "ctype.h"
  4 #include "stdlib.h"
  5 #include "math.h"
  6 #include "time.h"
  7 
  8 #define OK 1
  9 #define ERROR 0
 10 #define TRUE 1
 11 #define FALSE 0
 12 
 13 #define MAXSIZE 20 /* 存储空间初始分配量 */
 14 
 15 typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
 16 typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
 17 
 18 
 19 Status visit(ElemType c)
 20 {
 21     printf("%d ",c);
 22     return OK;
 23 }
 24 
 25 typedef struct Node
 26 {
 27     ElemType data;
 28     struct Node *next;
 29 }Node;
 30 typedef struct Node *LinkList; /* 定义LinkList */
 31 
 32 /* 初始化顺序线性表 */
 33 Status InitList(LinkList *L)
 34 {
 35     *L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
 36     if(!(*L)) /* 存储分配失败 */
 37         return ERROR;
 38     (*L)->next=NULL; /* 指针域为空 */
 39     
 40     return OK;
 41 }
 42 
 43 /* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
 44 Status ListEmpty(LinkList L)
 45 {
 46     if(L->next)
 47         return FALSE;
 48     else
 49         return TRUE;
 50 }
 51 
 52 /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
 53 Status ClearList(LinkList *L)
 54 {
 55     LinkList p,q;
 56     p=(*L)->next;           /*  p指向第一个结点 */
 57     while(p)                /*  没到表尾 */
 58     {
 59         q=p->next;
 60         free(p);
 61         p=q;
 62     }
 63     (*L)->next=NULL;        /* 头结点指针域为空 */
 64     return OK;
 65 }
 66 
 67 /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
 68 int ListLength(LinkList L)
 69 {
 70     int i=0;
 71     LinkList p=L->next; /* p指向第一个结点 */
 72     while(p)
 73     {
 74         i++;
 75         p=p->next;
 76     }
 77     return i;
 78 }
 79 
 80 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
 81 /* 操作结果:用e返回L中第i个数据元素的值 */
 82 Status GetElem(LinkList L,int i,ElemType *e)
 83 {
 84     int j;
 85     LinkList p;        /* 声明一结点p */
 86     p = L->next;       /* 让p指向链表L的第一个结点 */
 87     j = 1;        /*  j为计数器 */
 88     while (p && j<i)  /* p不为空或者计数器j还没有等于i时,循环继续 */
 89     {
 90         p = p->next;  /* 让p指向下一个结点 */
 91         ++j;
 92     }
 93     if ( !p || j>i )
 94         return ERROR;  /*  第i个元素不存在 */
 95     *e = p->data;   /*  取第i个元素的数据 */
 96     return OK;
 97 }
 98 
 99 /* 初始条件:顺序线性表L已存在 */
100 /* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */
101 /* 若这样的数据元素不存在,则返回值为0 */
102 int LocateElem(LinkList L,ElemType e)
103 {
104     int i=0;
105     LinkList p=L->next;
106     while(p)
107     {
108         i++;
109         if(p->data==e) /* 找到这样的数据元素 */
110             return i;
111         p=p->next;
112     }
113     
114     return 0;
115 }
116 
117 
118 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
119 /* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
120 Status ListInsert(LinkList *L,int i,ElemType e)
121 {
122     int j;
123     LinkList p,s;
124     p = *L;
125     j = 1;
126     while (p && j < i)     /* 寻找第i个结点 */
127     {
128         p = p->next;
129         ++j;
130     }
131     if (!p || j > i)
132         return ERROR;   /* 第i个元素不存在 */
133     s = (LinkList)malloc(sizeof(Node));  /*  生成新结点(C语言标准函数) */
134     s->data = e;
135     s->next = p->next;      /* 将p的后继结点赋值给s的后继  */
136     p->next = s;          /* 将s赋值给p的后继 */
137     return OK;
138 }
139 
140 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
141 /* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
142 Status ListDelete(LinkList *L,int i,ElemType *e)
143 {
144     int j;
145     LinkList p,q;
146     p = *L;
147     j = 1;
148     while (p->next && j < i) /* 遍历寻找第i个元素 */
149     {
150         p = p->next;
151         ++j;
152     }
153     if (!(p->next) || j > i)
154         return ERROR;           /* 第i个元素不存在 */
155     q = p->next;
156     p->next = q->next;          /* 将q的后继赋值给p的后继 */
157     *e = q->data;               /* 将q结点中的数据给e */
158     free(q);                    /* 让系统回收此结点,释放内存 */
159     return OK;
160 }
161 
162 /* 初始条件:顺序线性表L已存在 */
163 /* 操作结果:依次对L的每个数据元素输出 */
164 Status ListTraverse(LinkList L)
165 {
166     LinkList p=L->next;
167     while(p)
168     {
169         visit(p->data);
170         p=p->next;
171     }
172     printf("
");
173     return OK;
174 }
175 
176 /*  随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
177 void CreateListHead(LinkList *L, int n)
178 {
179     LinkList p;
180     int i;
181     srand(time(0));                         /* 初始化随机数种子 */
182     *L = (LinkList)malloc(sizeof(Node));
183     (*L)->next = NULL;                      /*  先建立一个带头结点的单链表 */
184     for (i=0; i<n; i++)
185     {
186         p = (LinkList)malloc(sizeof(Node)); /*  生成新结点 */
187         p->data = rand()%100+1;             /*  随机生成100以内的数字 */
188         p->next = (*L)->next;
189         (*L)->next = p;                        /*  插入到表头 */
190     }
191 }
192 
193 /*  随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
194 void CreateListTail(LinkList *L, int n)
195 {
196     LinkList p,r;
197     int i;
198     srand(time(0));                      /* 初始化随机数种子 */
199     *L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表 */
200     r=*L;                                /* r为指向尾部的结点 */
201     for (i=0; i<n; i++)
202     {
203         p = (Node *)malloc(sizeof(Node)); /*  生成新结点 */
204         p->data = rand()%100+1;           /*  随机生成100以内的数字 */
205         r->next=p;                        /* 将表尾终端结点的指针指向新结点 */
206         r = p;                            /* 将当前的新结点定义为表尾终端结点 */
207     }
208     r->next = NULL;                       /* 表示当前链表结束 */
209 }
210 
211 int main()
212 {
213     LinkList L;
214     ElemType e;
215     Status i;
216     int j,k;
217     i=InitList(&L);
218     printf("初始化L后:ListLength(L)=%d
",ListLength(L));
219     for(j=1;j<=1;j++)
220         i=ListInsert(&L,1,j);
221     printf("在L的表头依次插入1~5后:L.data=");
222     ListTraverse(L);
223     
224     printf("ListLength(L)=%d 
",ListLength(L));
225     i=ListEmpty(L);
226     printf("L是否空:i=%d(1:是 0:否)
",i);
227 //
228     i=ClearList(&L);
229     printf("清空L后:ListLength(L)=%d
",ListLength(L));
230     i=ListEmpty(L);
231     printf("L是否空:i=%d(1:是 0:否)
",i);
232 
233     for(j=1;j<=10;j++)
234         ListInsert(&L,j,j);
235     printf("在L的表尾依次插入1~10后:L.data=");
236     ListTraverse(L);
237 
238     printf("ListLength(L)=%d 
",ListLength(L));
239 
240     ListInsert(&L,1,0);
241     printf("在L的表头插入0后:L.data=");
242     ListTraverse(L);
243     printf("ListLength(L)=%d 
",ListLength(L));
244 
245     GetElem(L,5,&e);
246     printf("第5个元素的值为:%d
",e);
247     for(j=3;j<=4;j++)
248     {
249         k=LocateElem(L,j);
250         if(k)
251             printf("第%d个元素的值为%d
",k,j);
252         else
253             printf("没有值为%d的元素
",j);
254     }
255 
256 
257     k=ListLength(L); /* k为表长 */
258     for(j=k+1;j>=k;j--)
259     {
260         i=ListDelete(&L,j,&e); /* 删除第j个数据 */
261         if(i==ERROR)
262             printf("删除第%d个数据失败
",j);
263         else
264             printf("删除第%d个的元素值为:%d
",j,e);
265     }
266     printf("依次输出L的元素:");
267     ListTraverse(L);
268 
269     j=5;
270     ListDelete(&L,j,&e); /* 删除第5个数据 */
271     printf("删除第%d个的元素值为:%d
",j,e);
272 //
273     printf("依次输出L的元素:");
274     ListTraverse(L);
275 //
276     i=ClearList(&L);
277     printf("
清空L后:ListLength(L)=%d
",ListLength(L));
278     CreateListHead(&L,20);
279     printf("整体创建L的元素(头插法):");
280     ListTraverse(L);
281 //
282     i=ClearList(&L);
283     printf("
删除L后:ListLength(L)=%d
",ListLength(L));
284     CreateListTail(&L,20);
285     printf("整体创建L的元素(尾插法):");
286     ListTraverse(L);
287     
288     
289     return 0;
290 }

 

以上是关于线性表链式存储的主要内容,如果未能解决你的问题,请参考以下文章

线性表的链式存储结构 ( 链表 )

线性表的链式存储

线性表---链式存储(双向链表)

线性表---链式存储(双向链表)

线性表的链式存储

数据结构----线性表之链式存储