单链表的局限:
单链表可以用于表示任意的线性关系。
有些线性关系是循环的,即没有队尾元素。
循环链表的定义:
将单链表中的最后一个元素的next指针指向第一个元素。
在循环链表中可以定义一个“当前”指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有元素。
实现代码:
定义的头文件:
#ifndef __CIRCLELIST_H_ #define __CIRCLELIST_H_ typedef void CircleList; typedef struct _tag_CircleListNode CircleListNode; struct _tag_CircleListNode { CircleListNode* next; }; CircleList* CircleList_Create(); void CircleList_Destory(CircleList* list); void CircleList_Clear(CircleList* list); int CircleList_Length(CircleList* list); int CircleList_Insert(CircleList *list,CircleListNode *node,int pos); CircleListNode *CircleList_Get(CircleList* list,int pos); CircleListNode *CircleList_Delete(CircleList *list,int pos); CircleListNode *CircleList_DeleteNode(CircleList *list,CircleListNode *node); CircleListNode *CircleList_Reset(CircleList *list); CircleListNode *CircleList_Current(CircleList *list); CircleListNode *CircleList_Next(CircleList *list); #endif
实现的c文件:
#include <stdio.h> #include <malloc.h> #include "CircleList.h" typedef struct _tag_CircleList { CircleListNode header; CircleListNode *slider;//游标,用来遍历链表中的所有元素 int Length; }TCircleList; /* 创建一个头结点 */ CircleList* CircleList_Create()//O(1) { TCircleList *ret = (TCircleList*)malloc(sizeof(TCircleList)); if(ret != NULL) { ret->Length = 0; ret->header.next = NULL; ret->slider = NULL; } return ret; } /* 释放链表 */ void CircleList_Destory(CircleList* list)//O(1) { free(list); } /* 链表清空 */ void CircleList_Clear(CircleList* list)//O(1) { TCircleList *sList = (TCircleList*)list; if(sList != NULL) { sList->Length = 0; sList->header.next = NULL; sList->slider = NULL; } } /* 得到链表长度 */ int CircleList_Length(CircleList* list)//O(1) { TCircleList *sList = (TCircleList*)list; int ret = -1; if(sList != NULL) { ret = sList->Length; } return ret; } /* 链表的插入 */ int CircleList_Insert(CircleList *list,CircleListNode *node,int pos)//O(n) { TCircleList *sList = (TCircleList*)list; int ret = (sList != NULL)&&(pos >= 0)&&(node != NULL); int i; if( ret ) { CircleListNode *current = (CircleListNode*)sList; for(i=0; (i<pos)&&(current->next != NULL); i++) { current = current->next; } node->next = current->next; current->next = node; //从第一个元素插入 if(sList->Length == 0) { sList->header.next = node; sList->slider = node;//游标指向第一个节点 } sList->Length++; //如果是从第0个位置插入,最后一个节点指向第一个节点 if(current == (CircleListNode*)sList) { //定义一个指向最后的指针 CircleListNode *last = CircleList_Get(list,sList->Length-1); last->next = current->next; } } return ret; } /* 链表的查找 */ CircleListNode *CircleList_Get(CircleList* list,int pos)//O(n) { TCircleList *sList = (TCircleList*)list; CircleListNode *ret = NULL; int i; if( (0<=pos) && (sList != NULL) ) { CircleListNode *current = (CircleListNode*)sList; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; } return ret; } /* 单链表的删除 */ CircleListNode *CircleList_Delete(CircleList *list,int pos)//O(n) { TCircleList *sList = (TCircleList*)list; CircleListNode *ret = NULL; int i; if( (0<=pos) && (sList != NULL) && (sList->Length > 0)) { CircleListNode *current = (CircleListNode*)sList; CircleListNode *frist = (CircleListNode*)sList->header.next; CircleListNode *last = NULL; for(i=0; i<pos; i++) { current = current->next; } //删除第一个元素,last指向最后一个元素 if(current == (CircleListNode*)sList) { last = (CircleListNode*)CircleList_Get(sList,sList->Length-1); } ret = current->next; current->next = ret->next; sList->Length--; //如果删除的是第一节点,头结点指向第二节点,尾节点指向第二节点 if(last != NULL) { sList->header.next = ret->next; last->next = ret->next; } //如果删除的元素,恰好是游标所指向的位置,游标向后一个位置 if(ret == sList->slider) { sList->slider = ret->next; } //删除节点之后长度为0 if(sList->Length == 0) { sList->header.next = NULL; sList->slider = NULL; } } return ret; } CircleListNode *CircleList_DeleteNode(CircleList *list,CircleListNode *node) { TCircleList *sList = (TCircleList*)list; CircleListNode *ret = NULL; int i; if( sList != NULL ) { CircleListNode *current = (CircleListNode*)sList; for(i=0; i<sList->Length; i++) { if(current->next == node) { ret = current->next; break; } current = current->next; } if(ret != NULL) { CircleList_Delete(sList,i); } } return ret; } CircleListNode *CircleList_Reset(CircleList *list) { TCircleList *sList = (TCircleList*)list; CircleListNode *ret = NULL; if( sList != NULL ) { sList->slider = sList->header.next; ret = sList->slider; } return ret; } CircleListNode *CircleList_Current(CircleList *list) { TCircleList *sList = (TCircleList*)list; CircleListNode *ret = NULL; if( sList != NULL ) { ret = sList->slider; } return ret; } CircleListNode *CircleList_Next(CircleList *list) { TCircleList *sList = (TCircleList*)list; CircleListNode *ret = NULL; if( (sList != NULL) && (sList->slider != NULL) ) { ret = sList->slider; sList->slider = ret->next; } return ret; }
测试程序:
#include <stdio.h> #include "CircleList.h" #include <stdlib.h> struct Value { CircleListNode header; int v; }; int main(int argc, char *argv[]) { int i = 0; CircleList *list = CircleList_Create(); struct Value v1; struct Value v2; struct Value v3; struct Value v4; struct Value v5; struct Value v6; struct Value v7; struct Value v8; v1.v = 1; v2.v = 2; v3.v = 3; v4.v = 4; v5.v = 5; v6.v = 6; v7.v = 7; v8.v = 8; CircleList_Insert(list,(CircleListNode*)&v1,0); CircleList_Insert(list,(CircleListNode*)&v2,0); CircleList_Insert(list,(CircleListNode*)&v3,0); CircleList_Insert(list,(CircleListNode*)&v4,0); CircleList_Insert(list,(CircleListNode*)&v5,0); CircleList_Insert(list,(CircleListNode*)&v6,0); for(i=0; i<2*CircleList_Length(list); i++) { struct Value *pv = (struct Value*)CircleList_Get(list,i); printf("%d\n",pv->v); } while(CircleList_Length(list) > 0) { CircleList_Delete(list,0); } CircleList_Destory(list); printf("Press enter to continue ..."); getchar(); while(1); return 0; } /*测试代码 int i = 0; CircleList *list = CircleList_Create(); struct Value v1; struct Value v2; struct Value v3; struct Value v4; struct Value v5; struct Value v6; struct Value v7; struct Value v8; v1.v = 1; v2.v = 2; v3.v = 3; v4.v = 4; v5.v = 5; v6.v = 6; v7.v = 7; v8.v = 8; CircleList_Insert(list,(CircleListNode*)&v1,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v2,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v3,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v4,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v5,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v6,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v7,7); CircleList_Delete(list,0); for(i=0; i<2*CircleList_Length(list); i++) { struct Value *pv = (struct Value*)CircleList_Get(list,i); printf("%d\n",pv->v); } printf("\n"); while(CircleList_Length(list) > 0) { struct Value *pv = (struct Value*)CircleList_Delete(list,0); printf("%d\n",pv->v); } printf("\n"); //循环列表的骚操作 CircleList_Insert(list,(CircleListNode*)&v1,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v2,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v3,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v4,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v5,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v6,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v7,CircleList_Length(list)); CircleList_Insert(list,(CircleListNode*)&v8,CircleList_Length(list)); //通过游标获取元素 for(i=0; i<CircleList_Length(list); i++) { struct Value *pv = (struct Value*)CircleList_Next(list); printf("%d\n",pv->v); } printf("\n"); //重置链表的游标 CircleList_Reset(list); //约瑟夫问题 while(CircleList_Length(list) > 0) { struct Value *pv = NULL; //每次取出第三个 for(i=1;i<3;i++) { CircleList_Next(list); } pv = (struct Value*)CircleList_Current(list); printf("%d\n",pv->v); CircleList_DeleteNode(list,(CircleListNode*)pv); } CircleList_Destory(list); */