【数据结构】二、线性表:4.循环链表的定义及其基本操作(循环单链表,循环双链表的初始化、判空、判断头结点、尾结点、插入、删除)

文章目录

4.循环链表

4.1循环单链表

循环单链表(Circular Singly Linked List)是一种特殊类型的单链表,其中最后一个节点的指针指向头节点,形成一个循环。

循环单链表与普通单链表的主要区别在于,循环单链表的尾节点的指针不是指向 nullptr,而是指向头节点,形成一个闭环。这意味着,在循环单链表中,可以通过尾节点的指针重新回到头节点。

循环单链表的特点和优势:

  1. 尾节点的指针指向头节点,使得在遍历链表时不需要特别处理尾节点,方便实现循环遍历。
  2. 可以更容易地进行环形操作,如判断链表是否形成环、寻找环的起始点等。
  3. 循环单链表的插入和删除操作相对简单,因为不需要特别处理头部和尾部情况。
  4. 在使用循环单链表时,我们需要额外关注以下几点:
  5. 在插入和删除节点时,要确保更新指针的正确性,以避免死循环或链表中断。
  6. 在循环单链表中遍历时要设置终止条件,防止进入无限循环。
4.1.1初始化
c 复制代码
typedef struct LNode{  		//定义单链表结合类型
	ElemType data;			//每个结点存放一个一个数据元素
	struct LNode *next; 	//指针指向下一个结点
}LNode, *LinkList;

//初始化一个循环单链表
bool InitList(LinkList &L){
	L=(LNode *)malloc(sizeof(LNode));	//分配一个头结点
	if(L == NULL)  		//内存不足,分配失败
		return false;
	L->next = L;		//头结点next指向头结点
	return true;
}
4.1.2判断单链表是否为空

判断循环单链表是否为空,检查头结点指针是否指向它自己就行

c 复制代码
bool Empty(LinkList L){
	if(L->next == L)  //检查头结点指针是否指向它自己
		return true;
	else 
		return false;
}
4.1.3判断p结点是否为循环单链表的表尾结点
c 复制代码
//判断 p 结点是否为循环单链表的表尾结点
bool isTail(LinkList L, LNode *p)
{
	if(p->next == L)
		return true;
	else
		return false;
}
4.2循环双链表

循环双链表(Circular Doubly Linked List)是一种特殊类型的双向链表,其中最后一个节点的下一个指针指向头节点,头节点的前一个指针指向最后一个节点,形成一个循环。

循环双链表与普通双链表的主要区别在于,循环双链表既具有双向链表的前驱和后继关系,也具有循环遍历的能力。

循环双链表的特点和优势:

  1. 可以通过任意节点的前驱和后继指针方便地在双链表中进行插入和删除操作。
  2. 最后一个节点的下一个指针指向头节点,使得在遍历链表时不需要特别处理尾节点,可以很方便地实现循环遍历。
  3. 可以更容易地进行环形操作,如判断链表是否形成环、寻找环的起始点等。
  4. 循环双链表的插入和删除操作相对简单,不需要特别处理头部和尾部情况。

注意:在插入和删除节点时,要确保更新前驱和后继指针的正确性,以避免链表中断或形成其他错误结构。在循环双链表中遍历时要设置终止条件,防止进入无限循环。

4.2.1初始化

当我们在初始化一个双链表时,需要让头结点的前指针和后指针都指向头结点自己(而普通的双链表指向NULL)

c 复制代码
typedef struct DNode{
	ElemType data;
	struct DNode *prior,*next;
}DNode, *DLinkList;

//初始化空的循环双链表
bool InitDLinkList(DlinkList &L){
	L = (DNode*) malloc(sizeof(DNode));	//分配一个头结点
	if(L == NULL)		//内存不足,分配失败
		return false;
	L->prior = L;		//头结点的prior指向头结点
	L->next = L; 		//头结点的next指向头结点
	return true;		//初始化成功
}
4.2.2判断循环链表是否为空

检查头结点next指针是否指向它自己

c 复制代码
//判断循环链表是否为空
bool Empty(DLinkList L){
	if(L->next == L)
		return true;
	else
		return false;
}
4.2.3判断结点p是否为循环双链表的表尾结点

检查头结点next指针是否指向头结点

c 复制代码
bool isTail(DLinkList L, DNode  *p){
	if(p->next == L)
		return true;
	else
		return false;
}
4.2.4双链表的插入
c 复制代码
//在p结点之后插入s结点
bool InsertNextDNode(DNode *p, DNode *s){
	s->next = p->next;
	p->next->prior = s;//如果p没有后继结点,普通链表会出问题
	s->prior = p;
	p->next = s;
}
4.2.5双链表的删除
c 复制代码
//删除p的后继结点q
p->next = q->next;
q->next->prior = p;  //如果p没有后继结点,普通链表会出问题
free(q);
相关推荐
Dream it possible!9 小时前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
心抵鹊9 小时前
算法之双指针系列(一)
算法·leetcode
十二9 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
小此方10 小时前
[算法实战论:动态规划]回文串问题的dp解法,回文串问题的母题,以及以此为基础的派生题
算法·动态规划
Pniubi11 小时前
力扣560.和为k的子数组
算法·leetcode·职场和发展
D e re k ZH11 小时前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
Pniubi12 小时前
力扣438.找到字符串中所有字母异位词
算法·leetcode·职场和发展
zjxtxdy13 小时前
C++面向对象程序开发-类与对象
开发语言·c++
東隅已逝,桑榆非晚14 小时前
算法6. 双指针法-查找总价格为目标的两个商品
c++·学习·算法
Eyfcom14 小时前
〖物联网终端实战 01〗UWB 室内高精度定位:仓储 AGV 与人员的厘米级轨迹追踪
物联网·算法·物流系统·快递系统·跨境物流快递系统·物联网终端实战