线性表4:双向循环链表

线性表之带头双向循环链表 初学者必备:线性表之带头双向循环链表接口实现和一些链表必备思想 阅读详情

上一次介绍了单向循环链表,这一次介绍双向循环链表。

链表的特点

顾名思义,双向循环链表的结点中有两个指针域,一个指向直接后继,一个指向直接前驱。

链表的描述

描述: 数据域+两个指针域

typedef int datatype;

typedef struct node {
	datatype data;
	struct node * prior;
	struct node * next;
}dlinklist, *dlinklist_t;

基本操作

创建空链表

用malloc动态申请空间

dlinklist_t createDLinkList()
{
	//1.申请空间
	dlinklist_t H = (dlinklist_t)malloc(sizeof(dlinklist));
	if(NULL == H)
	{
		printf("malloc head node fail\n");
		return NULL;
	}

	//2.赋值:数据无效,两个指针都指向自己
	H->data = -1;
	H->prior = H;
	H->next = H;

	return H;
}

第一种插入方式:头插

头插,新结点永远插入第一项(头结点不是第一项,头结点后面才是第一项)
头插
代码的书写顺序可以有很多种,只要逻辑通顺即可。

int headInsert(dlinklist_t H, datatype x)
{
	//1.封装结点
	dlinklist_t pnew = (dlinklist_t)malloc(sizeof(dlinklist));
	if(NULL == pnew)
	{
		printf("malloc new node fail\n");
		return -1;
	}

	pnew->data = x;

	//2.接入头结点后面
	pnew->prior = H;
	pnew->next = H->next;
	H->next->prior = pnew;
	H->next = pnew;

	return 0;
}

输出链表

void showDLinkList(dlinklist_t H)
{
	dclinkPtr p = H->next;

	while(p != H)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	printf("\n");
}

查

单链表中,取第i个元素必须从头结点出发寻找。
按位置查找,查找第pos项元素,返回其地址

dlinklist_t searchPos(dlinklist_t H, int pos)
{
	int count = -1;
	dlinklist_t p = H;

	if(pos < 0)
	{
		printf("位置不合法:pos < 0\n");
		return NULL;
	}

	while(count < pos)
	{
		p = p->next;
		count++;

		if(p == H)
		{
			printf("位置不合法:pos > 表长\n");
			return NULL;
		}
	}

	return p;
}

第二种插入方式:任意位置插入新结点

要利用上面的查找函数searchPos()
在这里插入图片描述

int insertDLinkList(dlinklist_t H, int pos, datatype x)
{
	dlinklist_t pnew = NULL;//新增结点
	dlinklist_t p = searchPos(H, pos);//找位置
	if(NULL == p)	//位置合法不?
		return -1;

	//2.封装新结点
	pnew = (dlinklist_t)malloc(sizeof(dlinklist));
	if(NULL == pnew)
	{
		printf("malloc newnode fail\n");
		return -1;
	}

	pnew->data = x;

	//3.插入新增结点
	pnew->prior = p->prior;
	pnew->next = p;
	p->prior->next = pnew;
	p->prior = pnew;

	return 0;
}

删

删除结点
在这里插入图片描述

int deleteDLinkList(dlinklist_t H, int pos, datatype *x)
{
	//1.找位置
	dlinklist_t p = searchPos(H, pos);
	if(NULL == p)
		return -1;

	//2.删除
	p->prior->next = p->next;
	p->next->prior = p->prior;

	//3.释放该结点空间
	*x = p->data;
	free(p);
	p = NULL;

	return 0;
}

测试

dlinklist_t H = createDLinkList();
	if(NULL == H)
	{
		printf("createDLinkList fail\n");
		return -1;
	}

	headInsert(H, 4);
	headInsert(H, 3);
	headInsert(H, 2);
	headInsert(H, 1);
	showDLinkList(H);
	
	int pos = 2;
	dlinklist_t p = searchPos(H, pos);
	printf("下标%d = %d\n", pos, p->data);

	insertDLinkList(H, 2, 666);
	insertDLinkList(H, 2, 777);
	insertDLinkList(H, 2, 888);
	printf("insert: ");
	showDLinkList(H);

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

相关推荐

数据结构基础讲解(三)——线性表之循环链表专项练习

线性表是一种最基本、最常用的数据结构,它是一种线性结构,数据元素之间存在着**一对一**的线性关系。学习线性表,可以帮助我们理解数据结构的基本概念,并为学习其他更复杂的数据结构打下基础。

qq_74267366的博客 1397

【数据结构与算法 3】单链表

一、链表的特点 1、链表是一种非线性、非顺序的物理结构,是由多个节点组成。 2、链表采用的是“见缝插针”的存储方法,不要求内存连续,靠next指针关联起来。 3、链表的物理存储方式为随机存储,访问方式为顺序访问。 4、查找节点的时间复杂度为O(n),插入、删除节点的时间复杂度为O(1)。 5、链表适用于写操作多,读操作少的场景。 二、单链表 链表是有序的列表,但是它在内存中存储如下: 上图小结: 1、链表是以节点的方式来存储,是链式存储 2、每个节点包含data域,next域:指向下

学Java,找哪吒 9249

线性表——循环链表、双向链表

目录一、循环链表1、定义和特点 2、初始化循环链表 3、求循环链表的长度4、遍历循环链表找到值为x的结点个数(重点在于遍历操作)5、循环链表的典型应用——约瑟夫环 二、双向链表1、定义和特点 2、双向链表的类型声明3、求双向循环链表的长度 4、双向循环链表插入算法5、双向循环链表删除结点算法 注:以下算法中循环链表的节点声明同单链表 3、求循环链表的长度 4、遍历循环链表找到值为x的结点个数(重点在于遍历操作) 5、循环链表的典型应用——约瑟夫环 题解代码: 运行结果

m0_53359491的博客 839

数据结构之链表

链表是一种物理存储单元上非连续、非顺序的数据结构。前几篇我们讲到的数组也好,基于数组实现的栈和队列也好,都是静态的数据结构,都需要处理容量的问题。而链表是真正的动态数据结构,也是最简单的动态数据结构

zhaojun的博客 1万+

企业AI Agent审计与合规:从日志留存到网络联动的完整落地指南

审计日志是企业安全与合规体系的基石,尤其在AI Agent大规模接入业务后,如何完整记录其行为链成为新的挑战。从日志留存180天到PCI DSS合规要求,审计体系需要覆盖会话、推理、工具调用、数据访问等关键环节,并结合不可篡改的存储设计,确保证据链可信。同时,借鉴上网行为管理设备对应用行为控制审计的思路,以及Kismet被动监测网络流量的方法论,将网络侧审计与应用侧日志交叉验证,能有效发现越权和异常行为。本文从日志采集、全链路追踪、基线预警到多租户隔离,系统梳理了AI Agent审计与合规落地的关键路径,帮

weixin_32234493的博客 270

OTP/EEPROM 读取与处理

Camera OTP/EEPROM 读取与处理 文章目录Camera OTP/EEPROM 读取与处理1. OTP概念1.1 基本概念1.2 OTP存储类型1.3 OTP烧录信息类型1.4 OTP 作用2. 配置准备2.1 基本认识2.2 OTP/EEPROM配置3. OTP/EEPROM datasheet理解 以及 读取方式3.1 data sheet 内容3.2 一般OTP/EEPROM(e...

Understand-image 1万+

数据结构-链表

链表是一种常见的数据结构,由一系列节点构成,每个节点包含当前节点的数据和一个指针(单向链表)或者两个指针(双向链表),链表是一种动态的数据结构,可以动态的增删节点。它的特点是插入与删除数据十分方便,但寻找与读取数据的表现欠佳。

nice66660的博客 1369

版图学习汇总十一(DRC、LVS注意事项)

esd。

weixin_56071389的博客 2263

数据结构-双向链表

数据结构-双向链表

qq_43714814的博客 2325

开源人形机器人硬件生态:关键技术、产业链与低成本突破 | OpenLoong 社区线下分享会

本文将深入探讨人形机器人硬件平台的关键技术、产业链与核心部件以及降低成本的策略。从硬件平台的核心技术,到机器人核心零部件的详细介绍,再到产业链各环节的协同发展以及实现低成本化的创新思路,将一同剖析人形机器人迈向广泛应用所面临的挑战与机遇,展望其未来的发展趋势,为开发者和相关从业者提供一些参考与启示。

OpenLoong_的博客 2422

Handler相关面试题

常见面试题: Handler相关 一.谈一谈你对handler的认识,例如:机制和实现等。 handler机制图解: handler常见使用过程: ①.子线程向主线程发送消息: 在主线程中新建Handler实例,并重写handleMessage()方法用于处理子线程传过来的message; 通过Message.obtain()方法获取到消息msg,然后将需要传递给主线程的信息通过msg的what、obj等字段传递; 通过handler的sendMessage发送msg消息,然后在hand

龚礼鹏的博客 3171

链表的特点,单链表的定义、存储结构,单链表的基本操作(判断链表是否为空、销毁链表、清空链表、求链表表长、查找、插入、删除,建立单链表)

单链表是由表头唯一确定,因此单链表可以用头指针的名字来命名,若头指针名是L,则把链表称为表L。

weixin_72728720的博客 2770

STM32实战开发(65):STM32摄像头图像采集开发教程

我们将会详细介绍如何使用STM32进行摄像头控制、图像数据采集以及如何将采集到的图像数据传输到其他设备进行处理。通过这篇博客,您将能够掌握STM32与摄像头模块的图像采集技术,应用于各种图像处理场景。为了确保STM32能够正确接收图像数据,我们需要配置STM32的GPIO引脚,并通过外部中断捕获这些信号。为了实现更高效的图像采集,可以通过DMA进行数据传输,将图像数据直接从GPIO引脚存储到内存中。通过DMA传输,我们可以将采集到的图像数据直接存储在内存中的一个缓冲区,然后进行后续的图像处理。

2201_76125393的博客 2540

4.线性表-链表:单向循环链表与双向链表

摘要:本文介绍了两种链式存储结构——单向循环链表和双向链表。单向循环链表的特点是尾节点指向头节点形成闭环,可通过快慢指针法检测环并找到入口节点。双向链表则通过增加前驱指针实现双向遍历,详细阐述了头插法、尾插法和指定位置插入的操作步骤与图示。两种链表结构各具特点,适用于不同场景的数据存储需求。

m0_60698931的博客 371

Android系统开机时间分析与优化指南

本文系统阐述了Android开机时间优化的全流程技术方案。首先详细解析了从电源键按下到桌面显示的完整启动流程及关键事件序列,然后介绍了秒表计时、日志分析和自动化脚本三种测量方法。重点从底层和上层两个维度提出了具体优化措施:底层包括编译器优化、内核驱动裁剪和日志精简;上层涵盖系统服务参数调整、应用预优化和功能组件精简。最后提供了验证工具和方法,并强调优化需要在性能、功耗和功能间取得平衡。通过这套系统化方案,可有效提升Android设备的开机速度与用户体验。

学无止境 355

手把手教你学GPU的KMD专栏--3.4 中断处理机制与优化

记住,中断处理是GPU与CPU通信的"桥梁",没有高效的中断处理,GPU的性能将无法充分发挥。KMD通过"快进快出"原则、事件标志机制、GPU本机围栏等技术,实现高效、低延迟的中断处理。:GPU本机围栏机制允许GPU在满足特定条件(如围栏值达到某个阈值)时才触发中断,而不是每次围栏更新都触发中断,从而显著减少CPU唤醒次数,降低功耗。正如Microsoft GPU架构师在2022年WinHEC大会上指出:"没有好的中断处理,再强大的GPU也会被系统延迟拖垮。:多个GPU设备共享中断,导致中断处理混乱。

MHD0815的博客 112

第二章:4.线性表---循环链表和双向链表

前言:   循环链表:是另一种形式的链式存储结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成了一个环。因此,从表中任意节点出发均可找到表中的其他结点。      双向链表:前讨论的链式存储结构中个,每个结点都只有一个指示其后继元素的指针域,那么找下一个元素(NextElem) 的时间复杂度 为 O(1)。但是寻找直接前继元素必须要从头结点开始找,PriorElem ...

219

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

数据结构4:线性表->链表(2)(带哨兵位的双向循环链表的实现)

在一开始的情况下假设只有哨兵位则其中链表的next与prev均指向自己。

2301_78945620的博客 301

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

题目:设以带头结点的双向循环链表表示的线性表L=(a1,a2,…..,an).试写出一时间复杂度为o(n)的算法,将L改造为L=(a1,a3,…,an,a4,a2).

题目:设以带头结点的双向循环链表表示的线性表L=(a1,a2,…..,an).试写出一时间复杂度为o(n)的算法,将L改造为L=(a1,a3,…,an,a4,a2)

w_h007的博客 2404

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

java实现双向循环链表(循环双链表)

若是不清楚链表的结构,该篇文章不适合观看,这里只做文字说明,没有链表结构的图示

初心不忘、始终方得 6323

线性表的链式存储结构-双向链表及双向循环链表

目录1. 双向链表1.1 双向链表创建1.2 双向链表插入结点1.3 双向链表删除指定结点1.4 双向链表删除指定元素1.5 双向链表查找元素位置1.6 双向链表更新结点数据1.7 双向链表遍历2. 双向循环链表2.1 双向循环链表创建2.2 双向循环链表插入结点2.3 双向循环链表删除结点2.4 双向循环链表遍历 上一边文章我们介绍了单链表及循环链表,现在我们了解一下双向链表及双向循环链表。 1...

郭永明的技术专栏 3919

线性表—单链表、循环链表、双向链表。

单链表 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。 链表的存取必须从头指针开始,头指针指示链表的第一个结点(即第一个数据元素的存储映像,也称首元结点)。同时,最后一个数据元素没有直接后继,最后一个结...

weixin_46153942的博客 2051

数据结构——双向循环链表

链表的双向带头循环链表的实现

2301_76613753的博客 2126

线性表,双向链表,静态链表,循环链表(约瑟夫环)

通过前面的学习我们知道,具有“一对一”逻辑关系的数据,最佳的存储方式是使用线性表。那么,什么是线性表呢?线性表,全名为线性存储结构。使用线性表存储数据的方式可以这样理解,即“把所有数据用一根线儿串起来,再存储到物理空间中”。图 1 "一对一"逻辑关系的数据如图 1 所示,这是一组具有“一对一”关系的数据,我们接下来采用线性表将其储存到物理空间中。首先,用“一根线儿”把它们按照顺序“串”起来,如图 2 所示:图 2 数据的"线性"结构。

ZhangJiqun&191cm&85kg 704

4.线性表的循环链表、双向链表、以及应用

1.什么是线性表的循环链表、双向链表、以及应用?(What) 2.为什么需要线性表的循环链表、双向链表、以及应用?(Why) 3.如何学好线性表的循环链表、双向链表、以及应用?(How)

知其然,知其所以然 2078
上一篇: 线性表3:单向循环链表
下一篇: Dev-c++ 2:解决无法调试 & 调试步骤
hellohelloe
博客等级 码龄8年 18粉丝 15原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值