数据结构 --- 线性表(单链表)
工程目录结构:
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 }