线性表(单链表)
先把代码贴上,之后再详解
操作
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 }
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 }

浙公网安备 33010602011771号