循环链表总结

基本数据结构之-循环链表

参考资料:https://zh.wikipedia.org/wiki/%E5%BE%AA%E7%8E%AF%E9%93%BE%E8%A1%A8

  循环链表就像一个圆一样首尾相连,只要在初始化的时候把首尾链接起来,后面的操作和单链表什么差别,差别在于判断最后一个节点的条件变了,原来是判断最后一个结点的下一个节点是不是为空,现在判断的是下一个结点是不是首节点,这点需要特注意。

  为了偷懒这次直接没有单独用结构体封装一个size值,其实封装size值只是把一个O(1) 变成了O(n) 对于我们平时的学习没有什么影响,只要你不是使用随机函数,随机很大的数据没什么影响

  基本结构很简单,就是一个结构体,结构体里面嵌套了自己的一个一级指针

typedef struct _LISTNODE

{

struct _LISTNODE *next;

}ListNode, CircularList;

// 初始化,提别要主要,一定要让它们首尾相互咬合在一起

int Init_CircularList(CircularList **circularlist)

{ /* 操作结果:构造一个空的线性表circularlist */

if (circularlist == NULL)

{

exit(-1);

}

*circularlist = (CircularList *)malloc(sizeof(CircularList)); /* 产生头结点,并使circularlist指向此头结点 */

if (!*circularlist) /* 存储分配失败 */

exit(-2);

// 首尾咬合在一起

(*circularlist)->next = *circularlist; /* 指针域指向头结点 */

return 0;

}

接下来的操作和单链表很相似了,这儿就不过多的赘述,直接代码吧!

特别需要注意的地方就是,结尾的判断条件!!!!!

特别需要注意的地方就是,结尾的判断条件!!!!!

特别需要注意的地方就是,结尾的判断条件!!!!!

(我已经复制了三次了!!!!)

void Destroy_CircularList(CircularList *circularlist)

{ /* 操作结果:销毁线性表circularlist */

if (circularlist == NULL)

{

return;

}

if(circularlist!=NULL)

free(circularlist);

circularlist = NULL;

}

void Clear_CircularList(CircularList *circularlist) /* 改变circularlist */

{ /* 初始条件:线性表circularlist已存在。操作结果:将circularlist重置为空表 */

if (circularlist == NULL)

{

return;

}

if(circularlist!=NULL)

circularlist->next = circularlist;

}

int Empty_CircularList(CircularList *circularlist)

{ /* 初始条件:线性表circularlist已存在。操作结果:若circularlist为空表,则返回TRUE,否则返回FALSE */

if (circularlist == NULL)

{

return 0;

}

if (circularlist->next == circularlist) /* 空 */

return 1;

else

return 0;

}

int Length_CircularList(CircularList *circularlist)

{ /* 初始条件:circularlist已存在。操作结果:返回circularlist中数据元素个数 */

if (circularlist == NULL)

{

return -1;

}

int i = 0;

ListNode *pCurrent = circularlist->next; /* p指向头结点 */

while (pCurrent != circularlist) /* 没到表尾 */

{

i++;

pCurrent = pCurrent->next;

}

return i;

}

void * GetElem_CircularList(CircularList *circularlist, int Pos)

{ /* 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */

if (circularlist == NULL)

{

return NULL;

}

int j = 0; /* 初始化,j为计数器 */

ListNode *pCurrent = circularlist->next; /* p指向第一个结点 */

if (Pos < 0 || Pos > Length_CircularList(circularlist)) /* 第i个元素不存在 */

return NULL;

while (j < Pos)

{ /* 顺指针向后查找,直到p指向第i个元素 */

pCurrent = pCurrent->next;

j++;

}

return (void *)pCurrent;

}

int  LocateElem_CircularList(CircularList *circularlist, void* data, int(*compare)(void *data1, void *data2))

{ /* 初始条件:线性表circularlist已存在,compare()是数据元素判定函数 */

/* 操作结果:返回circularlist中第1个与e满足关系compare()的数据元素的位序。*/

/*           若这样的数据元素不存在,则返回值为0 */

if (circularlist == NULL)

{

return -1;

}

if (data == NULL)

{

return -2;

}

if (compare == NULL)

{

return -3;

}

int i = 0;

ListNode *pCurrent = circularlist->next; /* p指向第一个结点 */

while (pCurrent != circularlist)

{

if (compare(pCurrent, data)) /* 满足关系 */

return i;

pCurrent = pCurrent->next;

++ i;

}

return -1;

}

void *PriorElem_CircularList(CircularList *circularlist, void *data,int(*compare)(void *data1, void *data2))

{ /* 初始条件:线性表circularlist已存在 */

/* 操作结果:若cur_e是circularlist的数据元素,且不是第一个,则用pre_e返回它的前驱,*/

/*           否则操作失败,pre_e无定义 */

if (circularlist == NULL)

{

return NULL;

}

if (data == NULL)

{

return NULL;

}

if (compare == NULL)

{

return NULL;

}

ListNode *pCurrent = circularlist->next; /* p指向第一个结点 */

while (pCurrent!= circularlist) /* p没到表尾 */

{

if (compare(pCurrent->next,data))

{

return pCurrent;

}

pCurrent = pCurrent->next;

}

return NULL; /* 操作失败 */

}

void* NextElem_CircularList(CircularList *circularlist,void *data,int(*compare)(void *data1, void *data2))

{ /* 初始条件:线性表circularlist已存在 */

/* 操作结果:若cur_e是circularlist的数据元素,且不是最后一个,则用next_e返回它的后继,*/

/*           否则操作失败,next_e无定义 */

if (circularlist == NULL)

{

return NULL;

}

if (data == NULL)

{

return NULL;

}

if (compare == NULL)

{

return NULL;

}

ListNode *pCurrent = circularlist->next; /* p指向第一个结点 */

while (pCurrent != circularlist) /* p没到表尾 */

{

if (compare(pCurrent,data))

{

return pCurrent->next;

}

pCurrent = pCurrent->next;

}

return NULL; /* 操作失败 */

}

int Insert_CircularList(CircularList *circularlist, int Pos, void * data) /* 改变circularlist */

{ /* 在circularlist的第i个位置之前插入元素e */

if (circularlist == NULL)

{

return -1;

}

if (data == NULL)

{

return -2;

}

ListNode *pCurrent = circularlist; /* p指向头结点 */

int j = 0;

if (Pos < 0 || Pos > Length_CircularList(circularlist)) /* 无法在第i个元素之前插入 */

{

return -3;

}

while (j < Pos) /* 寻找第i-1个结点 */

{

pCurrent = pCurrent->next;

j++;

}

((ListNode *)data)->next = pCurrent->next;

pCurrent->next = data;

return 0;

}

int  DeleteByPos_CircularList(CircularList *circularlist, int Pos) /* 改变circularlist */

{ /* 删除circularlist的第i个元素,并由e返回其值 */

if (circularlist == NULL)

{

return -1;

}

ListNode *pCurrent = circularlist; /* p指向头结点 */

int j = 0;

if (Pos < 0 || Pos > Length_CircularList(circularlist)-1) /* 第i个元素不存在 */

return -1;

// 找到被删除结点的前驱

while (j < Pos) /* 寻找第i-1个结点 */

{

pCurrent = pCurrent->next;

j++;

}

pCurrent->next = pCurrent->next->next;

return 0;

}

int  DeleteByVal_CircularList(CircularList *circularlist, void* data) /* 改变circularlist */

{ /* 删除circularlist的第i个元素,并由e返回其值 */

if (circularlist == NULL)

{

return -1;

}

if (data == NULL)

{

return -2;

}

ListNode *pCurrent = circularlist; /* p指向头结点 */

while (pCurrent->next != circularlist)

{

// 找到被删除结点的前驱

if (pCurrent->next==data)

{

pCurrent->next = pCurrent->next->next;

break;

}

pCurrent = pCurrent->next;

}

pCurrent = pCurrent->next;

return 0;

}

void Traverse_CircularList(CircularList *circularlist, void(*Traverse)(void *data))

{ /* 初始条件:circularlist已存在。操作结果:依次对circularlist的每个数据元素调用函数vi() */

if (circularlist == NULL)

{

return;

}

if (Traverse == NULL)

{

return;

}

ListNode *pCurrent = circularlist->next; /* p指向首元结点 */

while (pCurrent != circularlist) /* p不指向头结点 */

{

Traverse(pCurrent);

pCurrent = pCurrent->next;

}

printf("\n");

}

时间: 2024-10-19 13:28:14

循环链表总结的相关文章

循环链表

?? 循环链表和单链表没有本质上的区别.唯一不同的链表的最后不再是空的了,而是指向了first头指针.仅仅有这样我们才会实现链表的循环功能,那么问题来了,我们在以下的函数功能中我们仅仅是须要把里面用的头指针的重用名换到first->next中.并且当中的计数器count也从1開始计数,这样就避免了在while的循环中第一步实行不下去. 废话不多说. 具体看wo的代码吧. #ifndef CirLinkList_H #define CirLinkList_H #include<iostream&

第33课 双向循环链表的实现

1. DTLib中双向链表的设计思路 (1)数据结点之间在逻辑上构成双向循环,这有别于Linux内核链表的实现. (2)头结点仅用于结点的定位,而Linux内核链表是将头结点作为循环的一部分. 2. 实现思路 (1)通过模板定义DualCircleList类,继承自DualLinkList类 (2)在DualCircleList内部使用Linux内核链表进行实现(另类实现) (3)使用struct list_head定义DualCircleList的头结点 (4)特殊处理:循环遍历时忽略头结点

C++__循环链表(练习)

循环链表 link.h #ifndef LINK_H_ #define LINK_H_ #define HEADER 0 #define TAIL -1 typedef int data_type; enum LINK_OP { LINK_ERR = -1, LINK_OK }; class LINK { private: data_type data; LINK *next; LINK *last; public: LINK(); LINK(data_type data); virtual ~

双向循环链表 初始化 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(DuLNode)

循环链表的基本操作

循环链表与普通链表最大的区别在于尾结点的指针域指向什么:普通链表的尾结点的指针域指向空(NULL),而循环链表的尾结点的指针域指向头结点,形成一个环! #include<iostream> #include<cstdlib> using namespace std; struct Node{ int data; Node* next; }; typedef Node* LinkList; //函数声明 void show(); void InitList(LinkList &

(线性结构)循环链表的初始化,增删减除结点。新手的了解

1.查找rear指针为O(1) 那么开始节点就为rear->next->next,也是O(1)   //大家可以想象从最后一个结点开始有什么好处2.head->next ==head 判断是否空表 //链表的定义 typedef struct CLinkList { ElemType data; struct CLinkList; } node ; 1 //插入结点 2 void ds_insert (node **pNode,int i) 3 { 4 node *temp; 5 nod

双向循环链表

//双向循环链表 typedef int datatype; //方便修改 //当然也可以写成模板来适应更多的数据类型 struct dclink{ datatype data;//数据定义 struct dclink *pre; struct dclink *next;//前驱和后继指针 }; class DCLink { public: DCLink();//default constructor DCLink(datatype data);//单参constructor void add(

算法导论13:双向循环链表 2016.1.13

今天这个又打了很长时间,本来觉得数据结构就是那样,不过是一种思维,但是实际上真正自己打和想象中差距还是很大,需要考虑到各种细节. 今天这个问题有一个比较有意思的应用,就是“约瑟夫环问题”. 具体可以参见百度百科: http://baike.baidu.com/link?url=poA1Aanlptc6yzP1puYhSw_0RQjRAplhPfHwk6eoiqMNxw6WigCEbexxZ8a9SUbrMGokpPbKNzVYw308xjeEw_ 读完问题就可以发现,这个问题用链表就是一个很完美

循环链表模板

#include <stdio.h> #include <stdlib.h> typedef struct lnode{ int data; struct lnode* next; } node,*linklist; void initlist(linklist &l){ linklist p=(linklist)malloc(sizeof(node)); p->next=p;//此处可以控制循环链表 l=p; } void InsertFront(linklist

链表(五)——单向循环链表

1.单向循环链表 区分单向链表和单向循环链表:单向循环链表的尾指针指向头结点. 2.单向循环链表的基本操作 #include <stdio.h> #include <malloc.h> #define NULL 0 typedef struct node { int data; struct node *next; }ElemSN; ElemSN * creat_link(int ms); //创建一个单向循环链表 void print_link(ElemSN *head); //