循环链表(单循环、双循环)(数据结构与算法)

循环链表:循环单链表、循环双链表

1. 循环单链表

在这里插入图片描述

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

在这里插入图片描述

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

循环单链表可以具有以下特点和优势:

  1. 尾节点的指针指向头节点,使得在遍历链表时不需要特别处理尾节点,方便实现循环遍历。
  2. 可以更容易地进行环形操作,如判断链表是否形成环、寻找环的起始点等。
  3. 循环单链表的插入和删除操作相对简单,因为不需要特别处理头部和尾部情况。
  4. 在使用循环单链表时,我们需要额外关注以下几点:
  5. 在插入和删除节点时,要确保更新指针的正确性,以避免死循环或链表中断。
  6. 在循环单链表中遍历时要设置终止条件,防止进入无限循环。

1.1 初始化一个循环单链表

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;
}

2.2 判断单链表是否为空

//判断循环单链表是否为空, 检查头结点指针是否指向它自己就行,如下图所示
bool Empty(LinkList L)
{if(L->next == L)  //检查头结点指针是否指向它自己return true;else return false;
}

在这里插入图片描述


2.3 判断 p 结点是否为循环单链表的表尾结点

//判断 p 结点是否为循环单链表的表尾结点
bool isTail(LinkList L, LNode *p)
{if(p->next == L)return true;elsereturn false;
}

在这里插入图片描述

从头结点找到尾部,时间复杂度为O(n), 从尾部找到头部,时间复杂度为O(1), 可以让L指向表尾元素(插入、删除时可能需要修改L)


2. 循环双链表

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

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

双链表:表头结点的prior指向NULL; 表尾结点的next指向NULL。

在这里插入图片描述
循环双链表:表头结点的prior指向表尾结点; 表尾结点的next指向头结点。
在这里插入图片描述

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

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

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

2.2 循环双链表的初始化

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

在这里插入图片描述

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

2.3 判断循环链表是否为空

typedef struct DNode     //创建循环双链表
{ElemType data;struct DNode *prior,*next;
}DNode, *DLinkList;void testDLinkList()
{//初始化循环双链表DLinkList L;InitDLinkList(L);//.......后续代码.......
}
//判断循环链表是否为空
bool Empty(DLinkList L)
{if(L->next == L)return true;elsereturn false;
}

2.4 判断结点p是否为循环双链表的表尾结点

bool isTail(DLinkList L, DNode  *p)
{if(p->next == L)return true;elsereturn false;
}

2.5 双链表的插入

//在p结点之后插入s结点
bool InsertNextDNode(DNode *p, DNode *s)
{s->next = p->next;	//将结点*s插入到结点*p之后p->next->prior = s;   //如果s->prior = p;p->next = s;
}

在这里插入图片描述

2.6 双链表的删除

//删除p的后继结点q
p->next = q->next;
q->next->prior = p;  //如果p没有后继结点,普通循环链表会出问题
free(q);

在这里插入图片描述

3. 知识回顾

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/130230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汽车标定技术(三)--XCP协议如何支持测量功能

目录 1. 概述 2. 测量方式 -- Poll 3. 测量方式 -- DAQ 3.1 ODT概念模型 3.2 DAQ List概念 3.3 ODT 绝对编号和相对编号 3.4 静态DAQ和动态DAQ模式 (1)静态DAQ (2)动态DAQ 4.小结 1. 概述 在该系列的首篇文章汽车标定技…

python把Word题库转成Excle题库

又到了一年一度的背题时刻,但是收到的题库是Word版的,页数特别多 话不多说,上代码,有图有真相,代码里面备注的很详细 # 导入所需库 import csv import os import refrom docx import Document from win32com import c…

tcp/ip协议2实现的插图,数据结构2 (15 - 章)

(40) 40 十五1 插口层 结构socket,sysent (41) 41 十五2 插口层 实用函数与file结构描述汇总 (42) 42 十五3 插口层 函socket,socreate,pr_usrreq (43)

工作数字化的中国历程 | 从 OA 到 BPM 到数字流程自动化

业务流程是由“活动”(或称“工作任务”)构成的,在企业里的所有工作是不是都叫流程,或者属于流程的一部分,这个概念很绕,我觉得没有必要去做学究气的辨析。我曾经提出过一个从工作的两个特性(产…

接口测试之什么是接口文档?

一、为什么要有接口文档? 没有接口文档的接口测试都是在抓瞎~前面的接口测试重点讲了协议,也讲了fiddler模拟接口请求,估计大部分还是不太懂怎么下手测试。这里小编专门拿出接口文档来做接口测试参考(估计很多测试小伙伴没见过接口…

Azure 机器学习 - 使用无代码 AutoML 训练分类模型

了解如何在 Azure 机器学习工作室中使用 Azure 机器学习自动化 ML,通过无代码 AutoML 来训练分类模型。 此分类模型预测某个金融机构的客户是否会认购定期存款产品。 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管…

java的线程池

线程池 可以做什么怎么创建 先了解下线程的生命周期 解释: 新建:线程创建但未被启动可运行:线程处于可运行的状态,当该线程有cpu的时间片后就可以执行睡眠:线程进入计时等待,等待一段指定的时间,可以通过wait()方法,sleep方法,join()方法等方式等待:线程进入等待模式,直到其…

抖音群控软件的作用是什么?

随着智能手机的普及和社交媒体的兴起,抖音成为了人们日常生活中不可或缺的一部分,许多人都通过抖音平台分享自己的生活、展示才艺、开展商业活动等。 然而,要想在抖音上获得更多的关注和收益,需要投入大量的时间和精力&#xff0…

【软件逆向】如何逆向Unity3D+il2cpp开发的安卓app【IDA Pro+il2CppDumper+DnSpy+AndroidKiller】

教程背景 课程作业要求使用反编译技术,在游戏中实现无碰撞。正常情况下碰撞后角色死亡,修改为直接穿过物体不死亡。 需要准备的软件 il2CppDumper。DnSpy。IDA Pro。AndroidKiller。 一、使用il2CppDumper导出程序集 将{my_game}.apk后缀修改为{my_…

基于jsp的采购管理系统的分析与实现

物资采购管理系统是针对内部而设计的,应用于的局域网,这样可以使得内部管理更有效的联系起来。企业采购管理系统是将IT技术用于企业采购信息的管理, 它能够收集与存储企业采购的档案信息,提供更新与检索企业采购信息档案的接口;提…

OpenGL ES入门教程(二)之绘制一个平面桌子

OpenGL ES入门教程(二)之绘制一个平面桌子 前言0. OpenGL绘制图形的整体框架概述1. 定义顶点2. 定义着色器3. 加载着色器4. 编译着色器5. 将着色器链接为OpenGL程序对象6. 将着色器需要的数据与拷贝到本地的数组相关联7. 在屏幕上绘制图形8. 让桌子有边框…

【iOS免越狱】利用IOS自动化WebDriverAgent实现自动直播间自动输入

1.目标 由于看直播的时候主播叫我发 666,支持他,我肯定支持他呀,就一直发,可是后来发现太浪费时间了,能不能做一个直播间自动发 666 呢?于是就开始下面的操作。 2.操作环境 iPhone一台 WebDriverAgent …

latex空心小写字母、数字

公式中可用 R \R R、 E \mathbb{E} E 等空心大写字母表示集合、期望等,latex 用 \mathbb 实现。有时想用空心的小写字母(虚数单位,因 i 已用来表示下标)和数字(指示函数用空心 1),此时 \mathbb…

用于 GaN-HEMT 功率器件仿真的 TCAD 方法论

目录 标题:TCAD Methodology for Simulation of GaN-HEMT Power Devices来源:Proceedings of the 26th International Symposium on Power Semiconductor Devices & ICs(14年 ISPSD)GaN-HEMT仿真面临的挑战文章研究了什么文章的创新点文章的研究方法…

asp.net docker-compose添加volume配置

打开docker-compose.override.yml下面添加 volumes:killsb-one-sqldata:external: false 服务下面添加volume配置 volumes:- "./dapr/config/social-client.json:/app/OidcSettings.json" 添加volume配置成功

【LeetCode刷题-队列与栈】--225.用队列实现栈

225.用队列实现栈 class MyStack {Queue<Integer> queue1;Queue<Integer> queue2;public MyStack() {queue1 new LinkedList<Integer>();queue2 new LinkedList<Integer>();}public void push(int x) {queue2.offer(x);while(!queue1.isEmpty()){que…

Docker学习——②

文章目录 1、Docker是什么1.1 Docker本质1.2 Docker的引擎迭代1.3 Docker和虚拟机的区别1.4 Docker 为什么比虚拟机资源利用率高&#xff0c;启动快&#xff1f;1.5 Docker 和 JVM 虚拟化的区别&#xff1f; 2、Docker架构3、Docker生态3.1 新时代软件诉求3.2 Docker 解决方案 …

C#知识总结 基础篇(下)

目录 5类和继承 5.1类继承 5.2访问继承的成员 5.3屏蔽基类的成员 5.4访问基类的成员 5.5虚方法与覆写方法 5.6构造函数的执行顺序 5.7成员访问修饰符 5.8抽象类 5.9密封类与静态类 6.表达式与运算符 6.1运算符和重载 7.结构 7.1结构体的感念。 7.2结构构造函数与…

C++笔记之动态数组的申请和手动实现一个简单的vector

C笔记之动态数组的申请和手动实现一个简单的vector code review! 文章目录 C笔记之动态数组的申请和手动实现一个简单的vector1.C语言中动态数组的申请与使用1.动态数组的申请使用new和delete使用std::vector 1.std::vector的底层实现2.手动实现一个简单的vector:使用一个指向…

Rocky 安装jdk17

1&#xff09;检测jdk是否安装&#xff1a; #运行 java -version如果提示安装&#xff0c;则输入N&#xff0c;跳过 2&#xff09;检测cpu 类型 若未安装查看linux处理器架构&#xff1a; #运行 hostnamectl #或运行 arch 3&#xff09;去官网下载相应的编译版本的Jdk Or…