15、循环链表
将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的链表称为单循环链表,简称循环链表。
CircleLinkList.h
1 #ifndef CIRCLELINKLIST_H 2 #define CIRCLELINKLIST_H 3 4 #include<stdio.h> 5 #include<stdlib.h> 6 #include<string.h> 7 8 9 //链表小结点 10 typedef struct CIRCLELINKNODE { 11 struct CIRCLELINKNODE* next; 12 }CircleLinkNode; 13 14 //链表结构体 15 typedef struct CIRCLELINKLIST { 16 CIRCLELINKNODE head; 17 int size; 18 }CircleLinkList; 19 20 //编写针对链表结构体操作的API函数 21 22 #define TRUE 1 23 #define FALSE 0 24 25 26 //比较回调 27 typedef int(*COMPARENODE)(CircleLinkNode*, CircleLinkNode*); 28 //打印回调 29 typedef void(*PRINTNODE)(CircleLinkNode*); 30 31 32 //初始化函数 33 CircleLinkList* Init_CircleLinkList(); 34 //插入函数 35 void Insert_CircleLinkList(CircleLinkList* clist,int pos, CircleLinkNode* data); 36 //获得第一个元素 37 CircleLinkNode* Front_CircleLinkList(CircleLinkList* clist); 38 //根据位置删除 39 void RemoveByPos_CircleLinkList(CircleLinkList* clist,int pos); 40 //根据值去删除 41 void RemoveByValue_CircleLinkList(CircleLinkList* clist, CircleLinkNode* data, COMPARENODE compare); 42 //获得链表的长度 43 int Size_CircleLinkList(CircleLinkList* clist); 44 //判断是否为空 45 int IsEmpty_CircleLinkList(CircleLinkList* clist); 46 //查找 47 int Find_CircleLinkList(CircleLinkList* clist, CircleLinkNode* data, COMPARENODE compare); 48 //打印结点 49 void Print_CircleLinkList(CircleLinkList* clist,PRINTNODE print); 50 //释放内存 51 void FreeSpace_CircleLinkList(CircleLinkList* clist); 52 53 54 #endif
CircleLinkList.c
1 #include"CircleLinkList.h" 2 3 4 5 //初始化函数 6 CircleLinkList* Init_CircleLinkList() { 7 8 CircleLinkList* clist = (CircleLinkList*)malloc(sizeof(CircleLinkList)); 9 clist->head.next = &(clist->head); 10 clist->size = 0; 11 12 return clist; 13 } 14 //插入函数 15 void Insert_CircleLinkList(CircleLinkList* clist, int pos, CircleLinkNode* data) { 16 if (clist == NULL) { 17 return; 18 } 19 if (data == NULL) { 20 return; 21 } 22 if (pos<0 || pos>clist->size) { 23 pos = clist->size; 24 } 25 //根据位置查找前一个结点 26 //辅助指针变量 27 CircleLinkNode* pCurrent = &(clist->head); 28 for (int i = 0; i < pos; i++) { 29 pCurrent = pCurrent->next; 30 } 31 //插入新元素 32 data->next = pCurrent->next; 33 pCurrent->next = data; 34 35 clist->size++; 36 } 37 //获得第一个元素 38 CircleLinkNode* Front_CircleLinkList(CircleLinkList* clist) { 39 return clist->head.next; 40 } 41 //根据位置删除 42 void RemoveByPos_CircleLinkList(CircleLinkList* clist, int pos) { 43 if (clist == NULL) { 44 return; 45 } 46 if (pos<0 || pos>clist->size) { 47 return; 48 } 49 //根据pos找上一个结点 50 //辅助指针变量 51 CircleLinkNode* pCurrent = &(clist->head); 52 for (int i = 0; i < pos; i++) { 53 pCurrent = pCurrent->next; 54 } 55 56 //缓存当前结点的下一个结点 57 CircleLinkNode* pNext = pCurrent->next; 58 pCurrent->next = pNext->next; 59 60 clist->size--; 61 62 } 63 //根据值去删除 64 void RemoveByValue_CircleLinkList(CircleLinkList* clist, CircleLinkNode* data, COMPARENODE compare) { 65 if (clist == NULL) { 66 return; 67 } 68 if (data == NULL) { 69 return; 70 } 71 //这个是循环链表,不能一直循环 72 CircleLinkNode* pPrev = &(clist->head); 73 CircleLinkNode* pCurrent = pPrev->next; 74 int i = 0; 75 for (; i < clist->size; i++) { 76 if (compare(pCurrent,data) == TRUE) { 77 pPrev->next = pCurrent->next; 78 break; 79 } 80 pPrev = pCurrent; 81 pCurrent = pPrev->next; 82 } 83 84 clist->size--; 85 86 } 87 //获得链表的长度 88 int Size_CircleLinkList(CircleLinkList* clist) { 89 return clist->size; 90 } 91 //判断是否为空 92 int IsEmpty_CircleLinkList(CircleLinkList* clist) { 93 if (clist->size == 0) { 94 return TRUE; 95 } 96 return FALSE; 97 } 98 //查找 99 int Find_CircleLinkList(CircleLinkList* clist, CircleLinkNode* data, COMPARENODE compare) { 100 if (clist == NULL) { 101 return FALSE; 102 } 103 if (data == NULL) { 104 return FALSE; 105 } 106 CircleLinkNode* pCurrent = clist->head.next; 107 int flag = -1; 108 for (int i = 0; i < clist->size; i++) { 109 if (compare(pCurrent, data) == TRUE) { 110 flag = i; 111 break; 112 } 113 pCurrent = pCurrent->next; 114 } 115 116 return flag; 117 } 118 //打印结点 119 void Print_CircleLinkList(CircleLinkList* clist, PRINTNODE print) { 120 if (clist == NULL) { 121 return; 122 } 123 CircleLinkNode* pCurrent = clist->head.next; 124 for (int i = 0; i < clist->size; i++) { 125 if(pCurrent==&(clist->head)){ 126 pCurrent = pCurrent->next; 127 printf("-----------------\n"); 128 } 129 print(pCurrent); 130 pCurrent = pCurrent->next; 131 } 132 } 133 //释放内存 134 void FreeSpace_CircleLinkList(CircleLinkList* clist) { 135 if (clist == NULL) { 136 return; 137 } 138 free(clist); 139 }
main.c
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include"CircleLinkList.h" 6 7 typedef struct PERSON { 8 CircleLinkNode* node; 9 char name[64]; 10 int age; 11 int score; 12 }Person; 13 14 void MyPrint(CircleLinkNode* data) { 15 Person* p = (Person*)data; 16 printf("Name:%s Age:%d Score:%d\n",p->name,p->age,p->score); 17 } 18 19 int MyCompare(CircleLinkNode* data1, CircleLinkNode* data2) { 20 Person* p1 = (Person*)data1; 21 Person* p2 = (Person*)data2; 22 if (strcmp(p1->name, p2->name) == 0 && p1->age == p2->age && p1->score == p2->score) { 23 return TRUE; 24 } 25 return FALSE; 26 } 27 28 int main() { 29 30 //创建循环链表 31 CircleLinkList* clist = Init_CircleLinkList(); 32 //创建数据 33 Person p1, p2, p3, p4, p5; 34 strcpy(p1.name, "aaa"); 35 strcpy(p2.name, "bbb"); 36 strcpy(p3.name, "ccc"); 37 strcpy(p4.name, "ddd"); 38 strcpy(p5.name, "eee"); 39 40 p1.age = 15; 41 p2.age = 16; 42 p3.age = 17; 43 p4.age = 18; 44 p5.age = 19; 45 46 p1.score = 55; 47 p2.score = 60; 48 p3.score = 70; 49 p4.score = 80; 50 p5.score = 90; 51 52 //数据入链表 53 Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p1); 54 Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p2); 55 Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p3); 56 Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p4); 57 Insert_CircleLinkList(clist, 100, (CircleLinkNode*)&p5); 58 59 60 //打印 61 Print_CircleLinkList(clist, MyPrint); 62 63 Person pDel; 64 strcpy(pDel.name, "ccc"); 65 pDel.age = 17; 66 pDel.score = 70; 67 //根据值删除 68 RemoveByValue_CircleLinkList(clist, (CircleLinkNode*)&pDel, MyCompare); 69 //打印 70 printf("------------------\n"); 71 Print_CircleLinkList(clist, MyPrint); 72 73 74 //释放内存 75 FreeSpace_CircleLinkList(clist); 76 77 78 79 system("pause"); 80 return 0; 81 }
运行结果: