模拟实现链表
该链表实现的功能:
1.指定位置之前插入元素
2.打印链表
3.删除指定元素
4.删除所有出现的指定元素
5.查找指定元素
6.对链表进行冒泡排序
7.头插
8.头删
9.尾插
10.尾删
11.销毁链表
下面进行分布详解:
pLinkNode BuyNode(DataType x) // 为新增节点开辟空间,并赋值
因为新增节点很多地方都用,所以将新增节点,封装成一个函数
注意:对开辟空间是否成功要做判断。
1 pLinkNode BuyNode(DataType x) //新增节点开辟空间 2 { 3 pLinkNode newNode = (pLinkNode)malloc(sizeof(LinkNode)); 4 if (newNode == NULL) 5 { 6 printf("out of memory\n"); 7 exit(EXIT_FAILURE); 8 } 9 newNode->data = x; 10 newNode->next = NULL; 11 return newNode; 12 }
pLinkNode Find(pLinkList pList, DataType x)
公用的查找函数,
返回找到元素的地址,
未找到返回NULL
1 pLinkNode Find(pLinkList pList, DataType x) //公用的查找函数 2 { 3 assert(pList); 4 pLinkNode cur = pList->phead; 5 while (cur!=NULL) 6 { 7 if (cur->data == x) 8 { 9 return cur; 10 } 11 cur = cur->next; 12 } 13 return NULL; 14 }
void Insert(pLinkList pList,pLinkNode pos,DataType x)
将指定元素插入到指定位置
分为两种情况
(1):当链表只有一个元素时进行头插
(2):链中有多个元素
例如: 将2插入3之前表
void Remove(pLinkList pList,DataType x)
只删除第一个匹配到的元素。
三种情况:
1.链表只有一个元素,进行头删
2.删除的是链表最后一个元素,进行尾删
3.删除的是中间节点
完整代码:
LinkList.h
1 #ifndef _LINK_LIST_ 2 #define _LINK_LIST_ 3 #define _CRT_SECURE_NO_WARNINGS 1 4 #include<stdio.h> 5 #include<stdlib.h> 6 #include<assert.h> 7 enum Select //j将所有选项用枚举列出来 8 { 9 EXIT, 10 INSERT, //指定位置之前插入 11 PRINT, //打印 12 REMOVE, //删除指定元素 13 REMOVEALL,//删除所有出现的元素 14 SEARCH, //查找指定元素 15 SORT, // 排序 16 PUSHF, //头插 17 PUSHB,//尾插 18 POPF, //头删 19 POPB, //尾删 20 DOSTROY, //销毁链表 21 EASER //删除指定位置的元素 22 }; 23 typedef int DataType; 24 typedef struct LinkNode //节点 25 { 26 DataType data; 27 struct LinkNode* next; 28 }LinkNode, *pLinkNode; 29 typedef struct LinkList //将头指针单独封装在一个结构体中 30 { 31 LinkNode* phead; 32 }LinkList, *pLinkList; 33 void Init(pLinkList pList);//初始化链表 34 void PrintList(pLinkList pList);//打印链表 35 void DestroyList(pLinkList pList);//销毁链表 36 void PushFront(pLinkList pList, DataType x);//头插 37 void PushBack(pLinkList pList, DataType x);//尾插 38 void PopFront(pLinkList pList); //头删 39 void PopBack(pLinkList pList);//尾删 40 void Insert(pLinkList pList, pLinkNode Pos, DataType x);//指定位置之前插入 41 pLinkNode Find(pLinkList pList, DataType x); //公用的查找函数 42 void Search(pLinkList pList, DataType x);//查找指定元素 43 void Exit(pLinkList pList); 44 void Remove(pLinkList pList, DataType x); //删除指定元素 45 void RemoveALL(pLinkList pList, DataType x); //删除所有出现的元素 46 void Erase(pLinkList pList, pLinkNode pos);//删除指定位置的元素 47 void BubbleSort(pLinkList pList);//对链表进行冒泡排序 48 #endif //_LINK_LIST_
LinkList.c
#include"LinkList.h" pLinkNode BuyNode(DataType x) //新增节点开辟空间 { pLinkNode newNode = (pLinkNode)malloc(sizeof(LinkNode)); if (newNode == NULL) { printf("out of memory\n"); exit(EXIT_FAILURE); } newNode->data = x; newNode->next = NULL; return newNode; } void Init(pLinkList pList)//初始化链表 { assert(pList); pList->phead = NULL; } void PrintList(pLinkList pList)//打印链表 { assert(pList); pLinkNode cur = pList->phead; while (cur != NULL) { printf("%d->", cur->data); cur = cur->next; } printf("NULL\n"); } void DestroyList(pLinkList pList)//销毁链表 { assert(pList); pLinkNode cur = pList->phead; pLinkNode del = NULL; while (cur != NULL) { del = cur; cur = cur->next; free(del); } pList->phead = NULL; } void PushFront(pLinkList pList, DataType x)//头插 { assert(pList); pLinkNode newNode = BuyNode(x); pLinkNode cur = pList->phead; newNode->next = cur; pList->phead = newNode; } void PushBack(pLinkList pList, DataType x) //尾插 { assert(pList); pLinkNode newNode = BuyNode(x); pLinkNode cur = pList->phead; if (cur == NULL) { pList->phead = newNode; return; } pLinkNode prev = NULL; while (cur!=NULL) { prev = cur; cur = cur->next; } prev->next= newNode; } void PopFront(pLinkList pList) //头删 { pLinkNode cur = pList->phead; if (cur == NULL) { printf("该链表无元素可删\n"); } else { pList->phead = cur->next; free(cur); cur = NULL; } } void PopBack(pLinkList pList)//尾删 { pLinkNode cur = pList->phead; pLinkNode prev = NULL; if (cur == NULL) { printf("该链表无元素可删\n"); } else if (cur->next == NULL) //链表中只有一个元素 { pList->phead = NULL; free(cur); } else { while (cur->next != NULL) { prev = cur; cur = cur->next; } free(cur); prev->next = NULL; } } void Insert(pLinkList pList, pLinkNode Pos, DataType x)//指定位置之前插入 { assert(pList); pLinkNode cur = pList->phead; pLinkNode newNode = BuyNode(x); if (Pos == cur) { PushFront(pList, x); } else if (Pos == NULL) { printf("输入位置错误\n"); return; } else { while (cur) { if (cur->next == Pos) { cur->next = newNode; newNode->next = Pos; } cur = cur->next; } } } pLinkNode Find(pLinkList pList, DataType x) //公用的查找函数 { assert(pList); pLinkNode cur = pList->phead; while (cur!=NULL) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } void Search(pLinkList pList, DataType x)//查找指定元素 { assert(pList); pLinkNode cur = NULL; cur = Find(pList, x); if (cur != NULL) { printf("该元素存在"); } printf("该元素不存在\n"); } void Remove(pLinkList pList, DataType x) //删除指定元素 { assert(pList); pLinkNode del = NULL; pLinkNode cur = NULL; DataType tmp; cur = Find(pList, x); if (cur == pList->phead) //链表只有一个元素时 { PopFront(pList); } else if (cur->next == NULL) //cur现在指向最后一个元素 { PopBack(pList); } else if (cur != NULL) { tmp = cur->data; cur->data = cur->next->data; cur->next->data = tmp; del = cur->next; cur->next = cur->next->next; free(del); } else { printf("该元素不存在\n"); } } void RemoveALL(pLinkList pList, DataType x) //删除所有出现的元素 { assert(pList); pLinkNode del = NULL; pLinkNode cur = pList->phead; DataType tmp; while (cur != NULL) { cur = Find(pList, x); if (cur == NULL) { return; } if (cur == pList->phead) //链表只有一个元素时 { PopFront(pList); } else if (cur->next == NULL) //cur现在指向最后一个元素 { PopBack(pList); } else { tmp = cur->data; cur->data = cur->next->data; cur->next->data = tmp; del = cur->next; cur->next = cur->next->next; free(del); } } } void Erase(pLinkList pList, pLinkNode pos)//删除指定位置的元素 { assert(pList); pLinkNode prev = NULL; pLinkNode del = NULL; pLinkNode cur = pList->phead; if (pos == NULL) { printf("该位置不存在\n"); } else if (cur == pos) { PopFront(pList); } else { while (cur !=pos) { prev = cur; cur = cur->next; } del = cur; prev->next = cur->next; free(del); } } void BubbleSort(pLinkList pList)//对链表进行冒泡排序 { assert(pList); pLinkNode cur = pList->phead; pLinkNode j = NULL; for (; cur != NULL; cur = cur->next) { for (j = cur->next; j != NULL; j = j->next) { if (cur->data>j->data) { DataType tmp = cur->data; cur->data = j->data; j->data = tmp; } } } }
test.c
1 #include"LinkList.h" 2 void menu() 3 { 4 printf("****************************************\n"); 5 printf("1.指定位置之前插入****2.打印链表********\n"); 6 printf("3.删除指定元素********4.删除所有指定的元素\n"); 7 printf("5.查找元素************6.链表排序*********\n"); 8 printf("7.头插****************8.尾插**************\n"); 9 printf("9.头删****************10.尾删**************\n"); 10 printf("11.销毁链表*********** 0.退出**************\n"); 11 printf("*******************************************\n"); 12 13 } 14 void Test() 15 { 16 int input; 17 DataType x; //插入的元素 18 DataType pos ; //插入的位置 19 LinkList List; 20 Init(&List); //一定要记得初始化 21 while (1) 22 { 23 menu(); 24 printf("请选择一个操作:\n"); 25 scanf("%d", &input); 26 switch (input) 27 { 28 case PRINT: 29 PrintList(&List); 30 break; 31 case PUSHF: 32 printf("请输入要插入的元素:\n"); 33 scanf("%d", &x); 34 PushFront(&List,x);//头插 35 break; 36 case SEARCH: 37 printf("请输入要查找的元素:\n"); 38 scanf("%d", &x); 39 Search(&List, x); 40 break; 41 case PUSHB: 42 printf("请输入要插入的元素:\n"); 43 scanf("%d", &x); 44 PushBack(&List, x);//头插 45 break; 46 case POPB: 47 PopBack(&List); 48 break; 49 case SORT: 50 BubbleSort(&List); 51 break; 52 case POPF: 53 PopFront(&List); 54 break; 55 case INSERT: 56 printf("请输入要插入的位置,要插入的元素\n"); 57 scanf("%d", &pos); 58 scanf("%d", &x); 59 Insert(&List, Find(&List, pos),x); //注意Find的参数 60 break; 61 case REMOVE: 62 printf("请输入删除的元素\n"); 63 scanf("%d", &x); 64 Remove(&List, x); 65 break; 66 case REMOVEALL: 67 printf("请输入删除的元素\n"); 68 scanf("%d", &x); 69 RemoveALL(&List, x); 70 break; 71 case DOSTROY: 72 DestroyList(&List); 73 break; 74 case EXIT: 75 DestroyList(&List); 76 exit(0); 77 break; 78 default: 79 printf("输入错误\n"); 80 break; 81 } 82 83 } 84 } 85 int main() 86 { 87 Test(); 88 system("pause"); 89 return 0; 90 }