一步一步学数据结构之1--1(循环链表)
今天记录下循环链表,其实循环链表也就是将单链表中最后一个数据元素的next指针指向第一个元素。
这里有一个概念需要说明下:
游标:在循环链表中可以定义一个“当前”指针,这个指针通常称为游标,可以通过这个游标来遍历链表中的所有元素
如图
这里介绍静态链表的常用操作:
l 创建循环链表
l 销毁循环链表
l 清空循环链表
l 获取表长度
l 把node插入pos位置
l 获取pos位置的元素
l 删除pos位置的元素
l 删除表中与node相同的元素(删除第一个匹配成功的)
l 重置游标
l 返回游标所指向的结点
l 游标后移
代码总分为三个文件:
CircleList.h : 放置功能函数的声明,以及表的声明,表结点的定义
CircleList.c : 放置功能函数的定义,以及表的定义
Main.c : 主函数,使用功能函数完成各种需求,不过一般用作测试
整体结构图为:
这里详细说下插入操作和删除操作:
插入操作:
如图
插入元素方法:
判断表和插入位置是否合法
由表头开始通过next域移动pos次后,当前元素的next域为要插入的位置
将新元素插入(和单链表插入方法相同)
表长度加1
判断是否为头插(就是头结点和首元素中间插入)
如果是头插的话,把尾结点的next域指向第一个元素(也就是头节点所指向的首元素)
如果之前表为空表,则游标指向插入的结点
删除操作:
如图
删除元素方法:
判断表和插入位置是否合法
由表头开始通过next域移动pos次后,当前元素的next指向的元素为要删除的元素
删除元素(和单链表删除元素相同)
表长度减1
判断是否删除的为首元素
如果删除的是首元素的话,把表尾结点的next域指向首元素
如果删除后表为空,则重置头结点的next域和游标
如果删除的结点正好游标也指向它,则游标后移
OK! 上代码:
CircleList.h
#ifndef _CIRCLELIST_H_ #define _CIRCLELIST_H_ typedef void CircleList; typedef struct _tag_CircleListNode CircleListNode; struct _tag_CircleListNode { CircleListNode* next; }; CircleList* CircleList_Create(); void CircleList_Destroy(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
CircleList.c
#include <stdio.h> #include <malloc.h> #include "CircleList.h" typedef struct _tag_CircleList { CircleListNode header; CircleListNode* slider; int length; }TCircleList; CircleList* CircleList_Create() { TCircleList* sList = (TCircleList*)malloc(sizeof(TCircleList)); if(NULL != sList) { sList->header.next = NULL; sList->slider = NULL; sList->length = 0; } return sList; } void CircleList_Destroy(CircleList* list) { free(list); } void CircleList_Clear(CircleList* list) { TCircleList* sList = (TCircleList*)list; if(NULL != sList) { sList->header.next = NULL; sList->slider = NULL; sList->length = 0; } } int CircleList_Length(CircleList* list) { TCircleList* sList = (TCircleList*)list; int ret = -1; if(NULL != sList) { ret = sList->length; } return ret; } int CircleList_Insert(CircleList* list, CircleListNode* node, int pos) { TCircleList* sList = (TCircleList*)list; int ret = (NULL!=sList)&&(NULL!=node)&&(0<=pos); int i = 0; 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(0 == sList->length) { sList->slider = node; } sList->length++; if(current == (CircleListNode*)sList) { CircleListNode* last = CircleList_Get(sList, sList->length-1); last->next = current->next; } } return ret; } CircleListNode* CircleList_Get(CircleList* list, int pos) { TCircleList* sList = (TCircleList*)list; CircleListNode* ret = NULL; int i = 0; if((NULL != sList)&&(0 < sList->length)) { 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) { TCircleList* sList = (TCircleList*)list; CircleListNode* ret = NULL; int i = 0; if((NULL != sList)&&(0 <= pos)&&(0 < sList->length)) { CircleListNode* current = (CircleListNode*)sList; CircleListNode* last = NULL; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; current->next = ret->next; sList->length--; if(current == (CircleListNode*)sList) { last = (CircleListNode*)CircleList_Get(sList, sList->length-1); } if(NULL != last) { sList->header.next = ret->next; last->next = ret->next; } if(ret == sList->slider) { sList->slider = ret->next; } if(0 == sList->length) { sList->slider = NULL; sList->header.next = NULL; } } return ret; } CircleListNode* CircleList_DeleteNode(CircleList* list, CircleListNode* node) { TCircleList* sList = (TCircleList*)list; CircleListNode* ret = NULL; int i = 0; if((NULL != sList)&&(NULL != node)) { CircleListNode* current = (CircleListNode*)sList; for(i=0; i<sList->length; i++) { if(node == current->next) { ret = current->next; break; } current = current->next; } if(NULL != ret) { CircleList_Delete(sList, i); } } return ret; } CircleListNode* CircleList_Reset(CircleList* list) { TCircleList* sList = (TCircleList*)list; CircleListNode* ret = NULL; if(NULL != sList) { sList->slider = sList->header.next; ret = sList->slider; } return ret; } CircleListNode* CircleList_Current(CircleList* list) { TCircleList* sList = (TCircleList*)list; CircleListNode* ret = NULL; if(NULL != sList) { ret = sList->slider; } return ret; } CircleListNode* CircleList_Next(CircleList* list) { TCircleList* sList = (TCircleList*)list; CircleListNode* ret = NULL; if(NULL != sList) { ret = sList->slider; sList->slider = ret->next; } return ret; }
Main.c
#include <stdio.h> #include <stdlib.h> #include "CircleList.h" typedef struct _tag_Value { CircleListNode header; int v; }Value; int main(void) { int i = 0; CircleList* list = CircleList_Create(); Value v1,v2,v3,v4,v5,v6,v7,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, 5); CircleList_Delete(list, 0); for(i=0; i<2*CircleList_Length(list); i++) { Value* p = (Value*)CircleList_Get(list, i); printf("%d ", p->v); } printf("\n"); while(CircleList_Length(list) > 0) { Value* p = (Value*)CircleList_Delete(list, 0); printf("%d ", p->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++) { Value* p = (Value*)CircleList_Next(list); printf("%d ", p->v); } printf("\n"); CircleList_Reset(list); while(CircleList_Length(list) > 0) { Value* pV = NULL; for(i=1; i<3; i++) { CircleList_Next(list); } pV = (Value*)CircleList_Current(list); printf("%d\n", pV->v); CircleList_DeleteNode(list, (CircleListNode*)pV); } CircleList_Destroy(list); return 0; }