线性表链式存储
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("\n"); 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\n",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 \n",ListLength(L)); 225 i=ListEmpty(L); 226 printf("L是否空:i=%d(1:是 0:否)\n",i); 227 // 228 i=ClearList(&L); 229 printf("清空L后:ListLength(L)=%d\n",ListLength(L)); 230 i=ListEmpty(L); 231 printf("L是否空:i=%d(1:是 0:否)\n",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 \n",ListLength(L)); 239 240 ListInsert(&L,1,0); 241 printf("在L的表头插入0后:L.data="); 242 ListTraverse(L); 243 printf("ListLength(L)=%d \n",ListLength(L)); 244 245 GetElem(L,5,&e); 246 printf("第5个元素的值为:%d\n",e); 247 for(j=3;j<=4;j++) 248 { 249 k=LocateElem(L,j); 250 if(k) 251 printf("第%d个元素的值为%d\n",k,j); 252 else 253 printf("没有值为%d的元素\n",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个数据失败\n",j); 263 else 264 printf("删除第%d个的元素值为:%d\n",j,e); 265 } 266 printf("依次输出L的元素:"); 267 ListTraverse(L); 268 269 j=5; 270 ListDelete(&L,j,&e); /* 删除第5个数据 */ 271 printf("删除第%d个的元素值为:%d\n",j,e); 272 // 273 printf("依次输出L的元素:"); 274 ListTraverse(L); 275 // 276 i=ClearList(&L); 277 printf("\n清空L后:ListLength(L)=%d\n",ListLength(L)); 278 CreateListHead(&L,20); 279 printf("整体创建L的元素(头插法):"); 280 ListTraverse(L); 281 // 282 i=ClearList(&L); 283 printf("\n删除L后:ListLength(L)=%d\n",ListLength(L)); 284 CreateListTail(&L,20); 285 printf("整体创建L的元素(尾插法):"); 286 ListTraverse(L); 287 288 289 return 0; 290 }