线性表(单链表)

先把代码贴上,之后再详解

操作

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 /*自定义*/
  4 #define INFEASIBLE 999999999/*超出线性表存储空间*/
  5 #define OK 1
  6 #define TRUE 1
  7 #define FALSE 0
  8 #define OVERFLOW 0/*溢出*/
  9 #define ERROR 0/*错误*/
 10 typedef int Status;
 11 typedef int ElemType; 
 12 /*线性表的单链表存储结构*/
 13 typedef struct LNode{
 14     ElemType data;
 15     struct LNode *next;
 16 }LNode,*LinkList;/* 另一种定义LinkList的方法 */
 17 
 18 Status InitList(LinkList &L)
 19 {
 20 /* 操作结果:构造一个空的线性表L */
 21     L=(LinkList)malloc(sizeof(LNode));/* 产生头结点,并使L指向此头结点 */
 22     if(!L)/* 存储分配失败 */
 23      exit(OVERFLOW);
 24      L->next=NULL;/* 指针域为空 */
 25      return OK; 
 26 }
 27 
 28 Status DestroyList(LinkList &L)
 29 { 
 30 /* 初始条件:线性表L已存在。操作结果:销毁线性表L */
 31    LinkList q;
 32    while(L)
 33    {
 34      q=L->next;
 35      free(L);
 36      L=q;
 37    }
 38    return OK;
 39 }
 40 
 41 Status ClearList(LinkList L) /* 不改变L */
 42 { 
 43 /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */
 44    LinkList p,q;
 45    p=L->next; /* p指向第一个结点 */
 46    while(p) /* 没到表尾 */
 47    {
 48      q=p->next;
 49      free(p);
 50      p=q;
 51    }
 52    L->next=NULL; /* 头结点指针域为空 */
 53    return OK;
 54 }
 55 
 56 Status ListEmpty(LinkList L)
 57 { 
 58 /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
 59    if(L->next) /* 非空 */
 60      return FALSE;
 61    else
 62      return TRUE;
 63 }
 64 
 65 int ListLength(LinkList L)
 66 { 
 67 /* 初始条件:线性表L已存在。操作结果:返回L中数据元素个数 */
 68    int LinkListLen=0;
 69    LinkList p=L->next; /* p指向第一个结点 */
 70    while(p) /* 没到表尾 */
 71    {
 72      LinkListLen++;
 73      p=p->next;
 74    }
 75    return LinkListLen;
 76 }
 77 Status GetElem(LinkList L,int i,ElemType &e)/* 算法2.8 */
 78 { 
 79  /* L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */
 80    int j=1; /* j为计数器 */
 81    LinkList p=L->next; /* p指向第一个结点 */
 82    while(p&&j<i) /* 顺指针向后查找,直到p指向第i个元素或p为空 */
 83    {
 84      p=p->next;
 85      j++;
 86    }
 87    if(!p||j>i) /* 第i个元素不存在 */
 88      return ERROR;
 89    e=p->data; /* 取第i个元素 */
 90    return OK;
 91 }
 92 
 93 Status compare(ElemType c1,ElemType c2) /* 数据元素判定函数(平方关系) */
 94 {
 95    if(c1==c2*c2)
 96      return TRUE;
 97    else
 98      return FALSE;
 99 }
100 
101 int LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
102 { 
103 /* 初始条件: 线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0) */
104 /* 操作结果: 返回L中第1个与e满足关系compare()的数据元素的位序。 */
105 /*           若这样的数据元素不存在,则返回值为0 */
106    int i=0;
107    LinkList p=L->next;
108    while(p)
109    {
110      i++;
111      if(compare(p->data,e)) /*找到这样的数据元素 */
112        return i;
113      p=p->next;
114    }
115    return 0;
116 }
117 
118 Status PriorElem(LinkList L,ElemType cur_e,ElemType &pre_e)
119 { 
120 /* 初始条件: 线性表L已存在 */
121 /* 操作结果: 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */
122 /*           返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE */
123    LinkList q,p=L->next; /* p指向第一个结点 */
124    while(p->next) /* p所指结点有后继 */
125    {
126      q=p->next; /* q为p的后继 */
127      if(q->data==cur_e)
128      {
129        pre_e=p->data;
130        return OK;
131      }
132      p=q; /* p向后移 */
133    }
134    return INFEASIBLE;
135 }
136 
137 Status NextElem(LinkList L,ElemType cur_e,ElemType &next_e)
138 { /* 初始条件:线性表L已存在 */
139    /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */
140    /*           返回OK;否则操作失败,next_e无定义,返回INFEASIBLE */
141    LinkList p=L->next; /* p指向第一个结点 */
142    while(p->next) /* p所指结点有后继 */
143    {
144      if(p->data==cur_e)
145      {
146        next_e=p->next->data;
147        return OK;
148      }
149      p=p->next;
150    }
151    return INFEASIBLE;
152 }
153 
154 Status ListInsert(LinkList &L,int i,ElemType e) /* 算法2.9*/
155 {
156 /* 在带头结点的单链线性表L中第i个位置之前插入元素e */
157     LinkList p=L;
158     int j=0;
159     while(p&&j<i-1)/* 顺指针向后查找,直到p指向第i-1个元素或p为空寻 */
160     {
161         p=p->next;
162         ++j;
163     }
164     if(!p||j>i-1) /* i小于1或者大于表长 */
165      return ERROR;
166      LinkList s=(LinkList)malloc(sizeof(LNode));/* 生成新结点 */
167      s->data=e;/* 插入L中 */
168      s->next=p->next;
169      p->next=s;
170      return OK;
171 }
172 
173 Status ListDelete(LinkList &L,int i,ElemType &e)/* 算法2.10*/
174 {
175     LinkList p;
176     int j=0;
177     while(p->next&&j<i-1)/*寻找第i个结点,并令p指向其前趋 */
178     {
179         p=p->next;
180         ++j;
181     }
182     if(!(p->next)||j>i-1)/* 删除位置不合理 */
183      return ERROR;
184      /*
185      p->next=p->next->next;
186      e=p->next->data;
187      */
188      LinkList q=p->next;/* 删除并释放结点 */
189      p->next=q->next;
190      e=q->data;
191      free(q);
192      return OK;
193 }
194 
195 void visit(ElemType c) /* ListTraverse()调用的函数(类型要一致) */
196 {
197    printf("%d ",c);
198 }
199 
200 Status ListTraverse(LinkList L,void(*visit)(ElemType))
201 {
202 /* vi的形参类型为ElemType,与bo2-1.c中相应函数的形参类型ElemType&不同 */
203 /* 初始条件:线性表L已存在 */
204 /* 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */
205    LinkList p=L->next;
206    while(p)
207    {
208      visit(p->data);
209      p=p->next;
210    }
211    printf("\n");
212    return OK;
213 }
214 void CreateList(LinkList &L,int n) /* 算法2.11 */
215 { 
216 /* 逆位序(插在表头)输入n个元素的值,建立带表头结构的单链线性表L */
217    int i;
218    L=(LinkList)malloc(sizeof(struct LNode));
219    L->next=NULL; /* 先建立一个带头结点的单链表 */
220    printf("请输入%d个数据\n",n);
221    for(i=n;i>0;--i)
222    {
223      LinkList p=(LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */
224      scanf("%d",&p->data); /* 输入元素值 */
225      p->next=L->next; /* 插入到表头 */
226      L->next=p;
227    }
228 }
229 
230 void CreateList2(LinkList &L,int n)
231 { /* 正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表 */
232    int i;
233    LinkList p,q;
234    L=(LinkList)malloc(sizeof(struct LNode)); /* 生成头结点 */
235    L->next=NULL;
236    q=L;
237    printf("请输入%d个数据\n",n);
238    for(i=1;i<=n;i++)
239    {
240      p=(LinkList)malloc(sizeof(struct LNode));
241      scanf("%d",&p->data);
242      q->next=p;
243      q=q->next;
244    }
245    p->next=NULL;
246 }
247 void MergeList(LinkList La,LinkList Lb,LinkList &Lc) /* 算法2.2,此句与algo2-2.c不同 */
248 {
249 /* 已知线性表La和Lb中的数据元素按值非递减排列。 */
250 /* 归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列 */
251    int i=1,j=1,k=0;
252    int La_len,Lb_len;
253    ElemType ai,bj;
254    InitList(Lc); /* 创建空表Lc */
255    La_len=ListLength(La);
256    Lb_len=ListLength(Lb);
257    while(i<=La_len&&j<=Lb_len) /* 表La和表Lb均非空 */
258    {
259      GetElem(La,i,ai);
260      GetElem(Lb,j,bj);
261      if(ai<=bj)
262      {
263        ListInsert(Lc,++k,ai);
264        ++i;
265      }
266      else
267      {
268        ListInsert(Lc,++k,bj);
269        ++j;
270      }
271    }
272    while(i<=La_len) /* 表La非空且表Lb空 */
273    {
274      GetElem(La,i++,ai);
275      ListInsert(Lc,++k,ai);
276    }
277    while(j<=Lb_len) /* 表Lb非空且表La空 */
278    {
279      GetElem(Lb,j++,bj);
280      ListInsert(Lc,++k,bj);
281    }
282 }
283 
284 void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)/*算法2.12*/
285 {
286 /* 已知单链线性表La和Lb的元素按值非递减排列。 */
287 /* 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列 */
288     LinkList pa,pb,pc; 
289     pa=La->next;
290     pb=Lb->next;
291     Lc=pc=La;/* 用La的头结点作为Lc的头结点 */
292     while(pa&&pb)
293     {
294         if(pa->data<=pb->data)
295         {
296             pc->next=pa;
297             pc=pa;
298             pa=pa->next;
299         }
300         else
301         {
302             pc->next=pb;
303             pc=pb;
304             pb=pb->next;
305         }
306     }
307     pc->next=pa?pa:pb;/* 插入剩余段 */
308     free(Lb);/* 释放Lb的头结点 */
309 }
310 Status equal(ElemType c1,ElemType c2)
311 {
312 /* 判断是否相等的函数,Union()用到 */
313    if(c1==c2)
314      return TRUE;
315    else
316      return FALSE;
317 }
318 
319 void Union(LinkList &La,LinkList Lb) /* 算法2.1,此句与algo2-1.c不同 */
320 {/* 将所有在线性表Lb中但不在La中的数据元素插入到La中 */
321    ElemType e;
322    int La_len,Lb_len;
323    int i;
324    La_len=ListLength(La); /* 求线性表的长度 */
325    Lb_len=ListLength(Lb);
326    for(i=1;i<=Lb_len;i++)
327    {
328      GetElem(Lb,i,e); /* 取Lb中第i个数据元素赋给e */
329      if(!LocateElem(La,e,equal)) /* La中不存在和e相同的元素,则插入之 */
330        ListInsert(La,++La_len,e);
331    }
332 }
View Code

main函数

 1 void CreateList_main()
 2 {
 3    int n=5;
 4    LinkList La,Lb,Lc;
 5    printf("按非递减顺序, ");
 6    CreateList2(La,n); /* 正位序输入n个元素的值 */
 7    printf("La="); /* 输出链表La的内容 */
 8    ListTraverse(La,visit);
 9    printf("按非递增顺序, ");
10    CreateList(Lb,n); /* 逆位序输入n个元素的值 */
11    printf("Lb="); /* 输出链表Lb的内容 */
12    ListTraverse(Lb,visit);
13    MergeList_L(La,Lb,Lc); /* 按非递减顺序归并La和Lb,得到新表Lc */
14    printf("Lc="); /* 输出链表Lc的内容 */
15    ListTraverse(Lc,visit);
16 }
17 
18 void Union_main()
19 {
20    LinkList La,Lb; /* 此句与algo2-1.c不同(因为采用不同的结构) */
21    Status i;
22    int j;
23    i=InitList(La);
24    if(i==1) /* 创建空表La成功 */
25      for(j=1;j<=5;j++) /* 在表La中插入5个元素 */
26        i=ListInsert(La,j,j);
27    printf("La= "); /* 输出表La的内容 */
28    ListTraverse(La,visit);
29    InitList(Lb); /* 也可不判断是否创建成功 */
30    for(j=1;j<=5;j++) /* 在表Lb中插入5个元素 */
31      i=ListInsert(Lb,j,2*j);
32    printf("Lb= "); /* 输出表Lb的内容 */
33    ListTraverse(Lb,visit);
34    Union(La,Lb);
35    printf("new La= "); /* 输出新表La的内容 */
36    ListTraverse(La,visit);
37 }
38 void MergeList_main()
39 {
40    LinkList La,Lb,Lc; 
41    int j,a[4]={3,5,8,11},b[7]={2,6,8,9,11,15,20};
42    InitList(La); /* 创建空表La */
43    for(j=1;j<=4;j++) /* 在表La中插入4个元素 */
44      ListInsert(La,j,a[j-1]);
45    printf("La= "); /* 输出表La的内容 */
46    ListTraverse(La,visit);
47    InitList(Lb); /* 创建空表Lb */
48    for(j=1;j<=7;j++) /* 在表Lb中插入7个元素 */
49      ListInsert(Lb,j,b[j-1]);
50    printf("Lb= "); /* 输出表Lb的内容 */
51    ListTraverse(Lb,visit);
52    MergeList(La,Lb,Lc);
53    printf("Lc= "); /* 输出表Lc的内容 */
54    ListTraverse(Lc,visit);
55 }
56 
57 int main()
58 {
59     printf("---------------------------------------------\nCreateList_main():\n");
60     CreateList_main();
61     printf("---------------------------------------------\nUnion_main():\n");
62     Union_main();
63     printf("---------------------------------------------\nMergeList_main():\n");
64     MergeList_main();
65     printf("---------------------------------------------\n");
66     return 0;
67 }
View Code

 

posted @ 2016-06-12 23:21  太过随意  阅读(159)  评论(0)    收藏  举报