线性表之循环链表的建立、查找、插入和删除(附C++程序)

[数据结构]链表之循环链表 需要注意的是,在循环链表中,插入和删除操作需要额外考虑最后一个节点的next指针和第一个节点的prev指针的修改。总之,循环链表是一种特殊的链表结构,在实现各种操作时需要注意其连续性和有序性,并针对特殊情况进行相应的处理。需要注意的是,在进行各种操作时,需要保证循环链表的连续性和有序性,以避免数据不一致等问题的发生。需要注意的是,在进行各种操作时,需要保证循环链表的连续性和有序性,即每个节点的next指针都指向下一个节点,并且最后一个节点的next指针指向头节点。但是,其实现简单,无需处理哈希冲突等问题。 阅读详情


一、循环链表的基本概念

定义:循环链表是另一种形式的链式存储结构。循环链表的任意元素都有一个前驱和一个后继,所有数据元素在关系上构成逻辑上的环。他的特点是表中尾结点的指针域不再是空,而是指向表头的节点,整个链表形成一个环。由此,从表中的任一点出发,均可找到链表中的其他的节点。循环链表又分为循环单链表和循环双链表。

二、循环单链表的算法

2.1 循环单链表的算法

循环链表是一个首尾相接的链表,将单链表的最后一个指针域改由NULL改为指向表头结点这就是单链式的循环链表,并称为循环单链表。
在这里插入图片描述
1.建立循环链表

(1)采用头插法建立循环单链表

该方法从一个空链表开始,读取数组a中的元素,生成新的节点,将读取的数据存储到新节点的数据域中,然后将新节点插入到当前的链表的表头上,直到结束为止。

//头插法创建循环单链表
void CreateList_L(LinkList &L, ElemType  a[], int n)
{
    LinkList *s;
    int i;
    L=(LinkList*)malloc(sizeof(LinkList));     //创建头节点
    L->next=L;         //置为空的循环链表
    for(int i=0;i<n;i++)
    {
        s = (LinkList*)malloc(sizeof(LinkList));      //创建新节点
        s->data = a[i];
        s->next = L->next;               //s指向下一个 
        L->next = s;                //再将s给单链表L的表头 
    }
}

(2)采用尾插法建立循环单链表

该方法是将新节点插到当前链表的表尾上,为此必须增加一个尾节点指针r,使其始终指向当前链表的尾节点,最后让r的next指向头节点。
//尾插法创建单链表

void CreateList_R(LinkList *&L,ElemType  a[], int n)
{
    LinkList *s,*r;
    int i;
    L=(LinkList*)malloc(sizeof(LinkList));             //创建头节点
    r=l;;
    for(int i=0;i<n;i++)
    {
        s=(LinkList*)malloc(sizeof(LinkList)); 
        s->data = a[i];
        r->next = s;
        r = s; 
    }
   r->next = NULL;
}

2.在循环单链表中查找元素值为x的节点

用p指针遍历循环单链表L,若当前节点的*p的data值为e,则返回其序号。否则返回0。

//按值查找
int FindLinkList(LinkList *L, ElemType e)
{
	int j=1;
	LinkList *p = L->next;
	while(p!=L && p->data != e)
	{
		p = p->next;
		j++;
	}
	if(p == L)
		return 0;
	else
		return j;
}

3.在循环单链表中插入节点操作

插入运算是将值为x的新节点插入到循环单链表的第i个位置上,也就是在第i个节点的之前插入一个新的节点。先在单链表中找到第i-1个节点,再在其后插入新的节点。

//在循环单链表的第i个元素之前插入元素x
void InsElem(LinkList *L, ElemType x, int i)
{
	int j=0;
	LinkList *p = L, *s;
	if(i<=0)  return 0;
	while(p!=L && j<i-1)    //查找第i-1个结点*p
	{         
		j++;
		p = p->next;
	}
	if(p == L)  return 0;        //未找到结点返回0
	else
	{
		s = (LinkList *)malloc(sizeof(LinkList));   //创建新结点
		s->data = x;                          //存放元素x
		s->next = p->next;                    //s指向i的元素位置,即p->next的指向
		p->next = s;                          //插入s后,那么p指向s
		return 0;                             //成功返回0
	}
}

4.在循环单链表中删除节点操作

先在循环单链表中找到第 i − 1 i-1 i−1个节点,继*p节点,再删去其后的节点q。

int DelElem(LinkList *&L, int i)
{
	int j=0;
	LinkList *p = L, *q;                //q是要被删除的元素
	if(i<=0)  return 0;
	while(p != L && j<i-1)
	{         //查找第i-1个结点*p
		j++;
		p = p->next;
	}
	if(p == L)  return 0;        //未找到结点返回0
	else{
		 q = p->next;
		if(q == L)  return 0;
		else{
			p->next = q->next;     //i-1指针指向i的指针
			free(q);               //释放q
			return 1;              //成功返回1
		}			
	}
}

2.2 循环双链表的算法

1.建立循环双链表

(1)采用头插法建立循环双链表

该方法从一个空链表开始,读取数组a中的元素,生成新的节点,将读取的数据存储到新节点的数据域中,然后将新节点插入到当前的链表的表头上,直到结束为止。算法如下:

void CreateDListF(DLinkList *&L, ElemType  a[], int n)
{
    DLinkList *s;
    int i;
    L=(DLinkList *)malloc(sizeof(DLinkList ));     //创建头节点
    L->next=L->prior=L;
    for(int i=0;i<n;i++)
    {
        s = (DLinkedlist *)malloc(sizeof(DLinkedlist ));
        s->data = a[i];
        s->next = L->next;               //s指向下一个 
        if ( L->next!=NULL)
        {
                L->next->prior=s;
        }      
        L->next = s;                //再将s给单链表L的表头 
        s->prior=L;
    }
}

(2)采用头插法建立循环双链表
该方法是将新节点插到当前链表的表位上,为止必须增加一个尾节点指针r,使其始终指向当前链表的尾节点,最后让r的next的指向头节点,头节点的p指向r节点,从而构成循环双链表。

循环双链表的尾插法:

void CreateDListR(DLinkList *&L, ElemType  a[], int n)
{
    DLinkedlist  *s, *r;
    int i;
    L=(DLinkList *)malloc(sizeof(DLinkList ));     //创建头节点
    r = L;
    for(i = 1; i< = n; i++)
    { 
        s =(DLinkList *)malloc(sizeof(DLinkList ));  
         s->data = a[i];
        r->next = s;
        s->prior = r;
        r = s;
    }
    r->next = L;
    L->prior=r;
}

2.在循环双链表中查找元素值为x的节点

用p指针遍历循环链表L,若当前节点的*p的data值为x,则返回其序号。若未找到,则返回0.

int  Finfnode(DLinkList *L, ElemType  x)
{ 
    DLinkList *p = L->next;
    int i=1;
    while(p != L && p->data != x)
    {  
        i++;
         p = p->next;
    } 
    if (p==L)   return 0;              //未找到时返回0;
    else return i;                       //找到时,返回序号
}

3.插入节点操作

假设在双链表中p所指的结点之后插入一个结点s,其操作语句描述为:

//在单链表的第i个元素之前插入元素x
int InsElem(DLinkedlist *&L, ElemType x, int i)
{
	int j=0;
	DLinkedlist *p = L, *s;
	while(p != L && j<i-1)  //查找第i-1个结点*p
	{         
		j++;
		p = p->next;
	}
	if(p == L)  return 0;        //未找到结点返回0
	else
	{
		s = (DLinkedlist *)malloc(sizeof(DLinkedlist ));   //创建新结点
		s->data = x;                          //存放元素x
		s->next = p->next;                    //s指向i的元素位置,即p->next的指向
		if (p->next != L)   p->next->prior=s;
		s->prior=p;
		p->next = s;                          //插入s后,那么p指向s
		return 1;                             //成功返回1
	}
}

4.插入节点操作

设要删除双链表中p结点的后继结点,其操作的语句为:
算法如下:

int DelElem((DLinkedlist *&L, ElemType x, int i)
{
	int j=0;
	DLinkedlist *p = L, *q;                //q是要被删除的元素
	if(i<=0)  return 0;
	while(p!=L && j<i-1)
	{         //查找第i-1个结点*p
		j++;
		p = p->next;
	}
	if(p == L)  return 0;        //未找到结点返回0
	else{
		 q = p->next;
		if(q == L)  return 0;
		p->next = q->next;     //i-1指针指向i的指针
		if (p->next != L)   p->next->prior=p
		free(q);               //释放q
		return 1;              //成功返回1
		}			
	}
}

[上一篇]:数据结构之双向链表的建立、查找、插入和删除(附C++程序)

线性表详解(静态链表、单链表、双向链表、循环链表) 目录申明 申明   本文章属于原创,其中参考了程杰老师《大话数据结构》行文结构和内容,侵删。 阅读详情

相关推荐

[源码和文档分享]基于QT实现的可视化链表(单链表、循环链表、双向链表)

1.1 题目 题号1:分别以单链表、循环链表、双向链表为例,实现线性表的建立、插入、删除、查找等基本操作。 要求:能够把建立、插入、删除等基本操作的过程随时显示输出来。 1.2 软件功能 功能分为三个板块,分别是单链表、循环链表、双向链表的建立、插入、删除等基本操作的过程。 单链表 查看单链表定义...

qq_38474647的博客 1047

C语言数据结构篇——循环链表的创建,插入,节点删除,打印等操作

C语言数据结构篇——循环链表的创建,插入,节点删除,打印等操作

m0_68382289的博客 2887

数据结构——线性表

1.线性表的定义与操作 2.顺序表 3.单链表 4.双链表 5.循环链表 6.静态链表 7.顺序表VS链表

FREEDOM’s blog 1866

循环链表的创建及可控输出

循环链表的创建以及基本操作 上篇我们讲了运用头插法和尾插法创建单链表的方法,和两种方法的比较。 接着我们学习循环链表的创建。 只要学会了单链表的创建,循环链表的创建就变得很简单。 循环链表创建 单链表的结构: 循环链表: 所谓循环链表,就是将单链表的尾结点 end 的指针域 也就是 end-&gt;next 指向头结点的地址 : end-&gt;next = head 。 这样就完成了循环链表...

Frank的博客 2313

本科课程【数据结构与算法】实验2——单链表与双向循环链表的插入、删除操作(C++实现)

大家好,我是【1+1=王】, 热爱java的计算机(人工智能)渣硕研究生在读。 如果你也对java、人工智能等技术感兴趣,欢迎关注,抱团交流进大厂!!! Good better best, never let it rest, until good is better, and better best. 近期会把自己本科阶段的一些课程设计、实验报告等分享出来,供大家参考,希望对大家有帮助。 持续更新。。。。。。。 一、 实验目的 掌握线性表的链表表示; 实现单链表的插入操作 实现单链表的删除操作 实现.

1+1=王的博客 2231

安卓直链APK安装拦截全解析:从Play Protect到厂商管控的应对指南

在移动应用分发领域,APK(Android Package)安装是开发者与用户交互的关键环节。其核心原理涉及安卓系统的安全沙箱机制与权限管理体系,旨在保护用户设备免受恶意软件侵害。这一机制的技术价值在于平衡了应用生态的开放性与安全性,但也在应用推广、企业内部分发等场景中带来了挑战。尤其在通过官网、广告等直链渠道分发APK时,常会遇到安装转化率骤降的问题。这背后主要受到Google Play Protect云端扫描、安卓系统安装权限模型演进(如Android 8.0+的安装源授权)以及设备制造商附加安全层(如

weixin_33894640的博客 462

循环链表的创建

循环链表和非循环链表其实创建的过程以及思路几乎完全一样,唯一不同的是,非循环链表的尾结点指向空(NULL),而循环链表的尾指针指向的是链表的开头。我们可以通过逐步的插入操作,创建一个新的节点,将原有链表尾结点的next指针修改指向到新的结点,新的结点的next指针再重新指向头部结点,然后逐步进行这样的插入操作,最终完成整个单项循环链表的创建。next表示指针,它永远指向自身的下一个结点,对于只有一个结点的存在,这个next指针则永远指向自身,对于一个链表的尾部结点,next永远指向开头。

七爷OK 1100

S7-1200与KINCO伺服通信实战:CM CANopen模块配置避坑指南(附完整PDO映射表)

本文详细解析了西门子S7-1200 PLC通过CM CANopen模块与KINCO伺服驱动器的通信配置全流程,重点解决PDO映射混乱、心跳报文配置错误等常见问题。提供硬件组态、参数设置、PDO映射模板及故障排查方案,助力工业自动化系统实现稳定高效的多轴运动控制。

2y3u4i5o6p的博客 1093

线性表之单链表的建立、删除、查找、插入、删除和归并(合并)(附C++程序)

本文详细介绍了单链表的建立、删除、查找、删除和归并的数据结构,并给出了c/c++的代码。

ch18328071580的博客 3928

保姆级教程:用Docker Compose在Linux上一键部署Milvus 2.5.8(附配置文件详解)

本文提供了一份详细的Milvus 2.5.8安装指南,通过Docker Compose在Linux系统上一键部署这款高性能向量数据库。教程涵盖环境准备、配置文件解析、服务启动验证及常见问题解决,帮助开发者快速搭建AI应用所需的基础设施。

weixin_28829629的博客 264

VBA学习笔记6:将多个工作表中满足条件的数据汇总到同一个工作表

VBA学习笔记6:将多个工作表中满足条件的数据汇总到同一个工作表

weixin_45355881的博客 4701

【C++数据结构与算法基础篇 -1】C++实现线性表的插入、删除、查找等操作

实现线性表的插入、删除、求表长、查找给定值 e、查找第 i 个位置元素等基本操作,要求编写的程序以菜单方式工作;用链式存储结构实现一元多项式的相加运算;利用双向链表实现通讯录的建立、删除、检索和列表,并可保存至文件,可重新装入

2301_76761656的博客 1678

CentOS8静默安装Oracle11.2.0.1

背景 新安装oracle,用静默安装方式就不需要安装图形界面了,省时省力。 前期准备工作与图形化安装一样,如创建用户|用户组、环境变量、内核参数、创建目录等. 可参考图形化安装,链接:https://blog.csdn.net/heroicpoem/article/details/104229369 环境 平台 版本 操作系统 centOS 8 Oracle 11gR2 1.响应文件 响应文件的内容就是图形化安装时手工设置的选项内容。 解压后,database/response/db

heroicpoem的专栏 4515

C/C++链表的基本操作(新建,输出,删除,插入,查找,逆序,排序,释放链表,链表长度计算,查找倒数第k节点的元素)

链表的一些操作 作为一个刚刚进入大学的萌新,从开学到现在(已经期末了),一直都是在看别人写的博客,终于有一天可以试着写自己的博客了,好了话不多说,开始进入正题 这周C语言的课刚刚教了链表,我就对这神奇的东西产生了兴趣,在我做完高数,线代,英语,C语言等作业之后,我开始捣鼓上课没听懂的链表。老师是用C语言教的,不过呢我习惯用C++了,毕竟方便嘿嘿,以下的代码就都是C++写的了。 好了正文开始了。 一...

chenyu-max 3027

万字长文介绍ARINC 653,以及在综合模块化航空电子设备(IMA)中的作用

ARINC 653 在综合模块化航空电子设备(IMA)的发展进程中扮演着极为关键的角色。从行业应用的实际情况来看,空客 A380 和波音 787 等先进飞机的航电系统套件充分体现了行业对 IMA 的高度重视和积极投入。在 IMA 架构下,核心软件具备强大的能力,能够支持多个航空电子应用程序的同时运行。这些应用程序可以并行开发,并高效地部署在同一个计算平台上,极大地提高了开发效率和系统集成度。ARINC 653 的出现为航空电子行业创造了一个充满活力和竞争力的商业环境。

2947

使用podspec创建iOS插件

概述 在WWDC 2014全球开发者大会上,苹果开放了动态库、App Extension等全新的功能,这为iOS插件化开发带来了可能。在iOS开发中,动态库是iOS提供的一种资源打包方式,可以将代码文件、头文件、资源文件和说明文档等集中在一起,并且可以在运行时进行动态加载。 目前,很多应用越做越复杂,应用程序也显得越来越臃肿。试想一下,如果将一些不常用的功能做成一个插件,然后根据用户的需求从网络中...

xiangzhihong8的专栏 985

考研数据结构--第二章:线性表

还在更新中~~ 文章目录线性表线性表的定义线性表的特点 线性表 线性表的定义 线性表是具有相同数据类型的n(n≥0)n(n\ge0)n(n≥0)个元素的有限序列,其中nnn为表长,当n=0n=0n=0时,该表为空表。 aia_iai​是线性表中的“第iii个”元素线性表中的位序。 a1a_1a1​是表头元素;ana_nan​是表尾元素。 除第一个元素外,每个元素有且仅有一个直接前驱;除最后一个元素外,每个元素有且仅有一个直接后继。 线性表的特点 表中元素个数有限。 表中元素具有逻辑上的顺序性,在序列中

蒟蒻 3829

Agent智能体:核心概念与架构——建立系统认知

本文摘要介绍了Agent智能体的核心概念与架构设计。主要内容包括: Agent定义与分类:阐述了Agent作为能够感知环境、决策执行的智能实体,重点分析了现代基于大语言模型(LLM)的Agent架构。 核心模块组成:详细说明了Agent的五大核心模块(感知、规划、记忆、工具和执行)及其交互流程。 UML建模展示:通过类图和序列图,清晰呈现了Agent系统的静态结构和动态执行过程。 项目结构设计:给出了模块化的代码目录结构,为实际开发提供参考框架。

lza_csdn2019的博客 627

NO.2数据结构线性表|线性表|顺序表|链表|单链表|双向链表|循环链表|静态链表|插入|删除

本文介绍了线性表及其实现方式。线性表是n个具有相同特性的数据元素组成的有序序列,具有"四个一"的特点。线性表的主要实现方式包括顺序表和链表。顺序表通过连续内存存储元素,具有随机存取优势但插入删除效率低;链表通过指针连接元素,分为单链表、双向链表和循环链表,插入删除效率高但存储密度低。静态链表则用数组实现链式结构。文章详细比较了各种实现的优缺点,并阐述了基本操作如建立、插入和删除的实现方法。顺序表适用于数据量小且少改动的场景,链表则适合频繁增删的情况。

ChoSeitaku的博客 986

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

数据结构--线性表(顺序表、单链表、双链表、循环链表、静态链表)

线性表是具有相同数据类型的n (n>=0)个数据元素的有限序列,其中n为表长,当n = 0时线性表是一个空表。若用 L 命名线性表,则其一般表示为注1.Ai 是线性表中的 “第 i 个” 元素线性表中的位序(位序从1开始,数组下标从0开始2.A1是表头元素;an是表尾元素。3.除第一个元素外,每个元素有且仅有一个直接前驱;除最后一个元素外,每个元素有且仅有一个直接后继顺序表――用顺序存储的方式实现线性表顺序存储。

weixin_46858088的博客 3965

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C、C++介绍线性表基本操作

线性表的基本操作 文章目录线性表的基本操作前言一、顺序表1、定义2、初始化构建3、插入操作1、算法2、代码实现4、删除操作1、算法2、代码实现5、合并操作二、链表1.单链表2.循环链表3.双向链表总结1 前言 线性表包括两部分顺序表和链表 提示:以下是本篇文章正文内容,下面案例可供参考 一、顺序表 #define LISST_INIT_SIZE 100 #define LISTINCREMENT 10 #define OK 0 #define OVERFLOW 1 typedef int Elem

振宇的博客 3551

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C++线性表

线性表是一种最简单、最基本也是最常用的线性结构。在线性结构中,数据元素之间存在一个对一个的线性关系,数据元素“一个接一个地排列”。在一个线性表中,数据元素的类型是相同的,或者说,线性表是由同一类型的数据元素构成的。在实际问题中,线性表的例子很多,如学生自然情况信息表、工资信息表等都是线性表。线性表是具有相同数据类型的n(n≥0)个数据元素的有限序列,通常记为:(a1,a2, …, ai-1, ai, ai+1, …, an)。其中,n为数据元素个数,称为表长。当n=0时称为空表。

m0_51415606的博客 1236

【数据结构篇C++实现】- 线性表 - 顺序表和链表

线性表知识总结,一文搞懂什么是顺序表与链表,以及常见的操作

陈七的博客,学习知识分享,期待与大家的交流 4256

数据结构详解——线性表(C++实现)

线性表   线性表是最常用且是最简单的一种数据结构。形如:A1、A2、A3….An这样含有有限的数据序列,我们就称之为线性表。 线性表 一、线性表的定义 二、线性表的抽象数据类型 三、线性表的顺序存储 1. 顺序存储定义 2. 顺序存储的实现方式 3. 顺序存储的优缺点 四、线性表的链式存储 1. 链式存储定义 2. 链式存储的实现方式 链式存储的优缺点 五、其他线性表 循环链...

Quanfita的博客 6万+

数据结构第二章——线性表的定义和特点

数据结构第二章——线性表的定义和特点 线性表的定义和特点 线性表是具有相同特性的数据元素的一个有限序列 其中数据元素的个数n定义为表的长度 当n = 0时称为空表 线性表的逻辑特征: 在非空的线性表,有且仅有一个开始结点a1,他没有直接前驱,儿仅有一个直接后继a2 有且仅有一个终端结点an,它没有直接后继,而仅有一个直接前驱an-1 其余的内部结点ai(2 <= i <= n - 1)都仅有一个直接前驱ai-1和一个直接后继ai+1 线性表的顺序存储表示 线性表的顺序表示又称为顺序存储

haust_允谦的博客 9696

【数据结构与算法】02:线性表

第一章:线性表 一、线性表 1.线性表定义 注意:同一线性表中的元素必定具有相同的特性,数据元素之间的关系是线性关系。 2.线性表逻辑特征: 3.线性表类型定义 二、线性表的顺序表示与实现 1.顺序表定义: 注意:线性表顺序存储结构必须占用一片连续的存储空间,知道某个元素的存储位置就可以计算其他元素的存储位置。 2.顺序表存储表示: c动态内存分配: cpp动态存储分配: 3.顺序表操作实现: (1)基本操作: 基本操作 函数 初始化 InitList

https://blog.csdn.net/m0_74834215 1697
上一篇: 线性表之单链表的建立、删除、查找、插入、删除和归并(合并)(附C++程序)
下一篇: 线性表之双向链表的建立、查找、插入和删除(附C++程序)
陈小虾
博客等级 码龄11年 226粉丝 91原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值