【链表-双向链表】

news2024/12/28 4:15:12

链表-双向链表

  • 1.链表的分类
    • 1.1 分类依据
    • 1.2 常用类型
  • 2.双向链表的
    • 2.1 双向链表的结构
    • 2.2 双向链表的操作
      • 2.2.1 **初始化**
      • 2.2.2 **尾插**
      • 2.2.3 **头插**
      • 2.2.4 **尾删**
      • 2.2.5 **头删**
      • 2.2.6 在pos位置之后插入数据
      • 2.2.7 删除pos节点
      • 2.2.8 查找
      • 2.2.9 销毁

1.链表的分类

1.1 分类依据

单向or双向
在这里插入图片描述
带头or不带头
(一般会称d1为头节点,但实际上head这个哨兵节点才是头节点)
在这里插入图片描述
循环or不循环
在这里插入图片描述
综上所述,222共有8种链表

1.2 常用类型

我们一般最常用的就是单链表和双链表。
单链表:不带头单向不循环链表
在这里插入图片描述

双向链表:带头双向循环链表
在这里插入图片描述

2.双向链表的

2.1 双向链表的结构

双向链表包含三个部分,:
1.数据
2.指向下一个节点的指针
3.指向上一个节点的指针

struct ListNode
{
	int data;
	struct ListNode* next;
	struct ListNode* prev;
}

ps:单链表和双向链表的初始状态?
单链表为空链表
双向链表剩下一个头结点(即哨兵位)

2.2 双向链表的操作

2.2.1 初始化

方法一

void LTInit(LTNode** pphead);
void LTInit(LTNode** pphead)
{
	//给双向链表创建一个哨兵位
	*pphead = LTBuyNode(-1);//哨兵位不存储有效数据
}

方法二

LTNode* LTInit();
LTNode* LTInit()
{
	LTNode* phead = LTBuyNode(-1);
	return phead;
}

打印双向链表
在这里插入图片描述

void LTPrint(LTNode* phead);
void LTPrint(LTNode* phead)
{
	LTNode* pcur = phead->next;
	while (pcur != phead)
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("\n");
}

void LTInit(LTNode** pphead)
{
	//给双向链表创建一个哨兵位
	*pphead = LTBuyNode(-1);//哨兵位不存储有效数据
}

2.2.2 尾插

在这里插入图片描述

//尾插
void LTPushBack(LTNode* phead, LTDataType x);
//尾插
void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);//哨兵位空,那就不是一个有效的双向链表
	LTNode* newnode = LTBuyNode(x);

	//phead phead->prev newnode
	newnode->prev = phead->prev;//新节点头指向原链表的尾节点
	newnode->next = phead;//新节点尾节点指向哨兵位

	phead->prev->next = newnode;//原本的尾节点phead->prev指向新的尾节点
	phead->prev = newnode;//哨兵位指向新的尾节点
}

2.2.3 头插

在这里插入图片描述

void LTPushFront(LTNode* phead, LTDataType x); 
void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* newnode = LTBuyNode(x);

	//phead newnode phead->next
	newnode->next = phead->next;
	newnode->prev = phead;

	phead->next->prev = newnode;
	phead->next = newnode;
}

2.2.4 尾删

在这里插入图片描述

void LTPopBack(LTNode* phead);
void LTPopBack(LTNode* phead)
{
	//链表必须有效且链表不能为空(只有一个哨兵位)
	assert(phead && phead->next != phead);

	LTNode* del = phead->prev;
	//phead del->prev del
	del->prev->next = phead;
	phead->prev = del->prev;

	//删除del节点
	free(del);
	del = NULL;
}

2.2.5 头删

在这里插入图片描述

void LTPopFront(LTNode* phead);
void LTPopFront(LTNode* phead)
{
	assert(phead && phead->next != phead);

	LTNode* del = phead->next;

	//phead del del->next
	phead->next = del->next;
	del->next->prev = phead;

	//删除del节点
	free(del);
	del = NULL;
}

2.2.6 在pos位置之后插入数据

在这里插入图片描述

void LTInsert(LTNode* pos, LTDataType x);
void LTInsert(LTNode* pos, LTDataType x)
{
	assert(pos);

	LTNode* newnode = LTBuyNode(x);
	//pos newnode pos->next
	newnode->next = pos->next;
	newnode->prev = pos;

	pos->next->prev = newnode;
	pos->next = newnode;
}

2.2.7 删除pos节点

在这里插入图片描述

void LTErase(LTNode* pos);
void LTErase(LTNode* pos)
{
	//pos理论上来说不能为phead,但是没有参数phead,无法增加校验
	assert(pos);
	//pos->prev pos pos->next
	pos->next->prev = pos->prev;
	pos->prev->next = pos->next;

	free(pos);
	pos = NULL;
}

PS:LTErase参数理论上要传二级,因为我们需要让形参的改变影响到实参,但是为了保持接口一致性才传的一级。

2.2.8 查找

LTNode* LTFind(LTNode* phead, LTDataType x);
LTNode* LTFind(LTNode* phead, LTDataType x)
{
	LTNode* pcur = phead->next;
	while (pcur != phead)
	{
		if (pcur->data == x)
		{
			return pcur;
		}
		pcur = pcur->next;
	}
	//没有找到
	return NULL;
}

2.2.9 销毁

在这里插入图片描述

void LTDesTroy(LTNode* phead);
void LTDesTroy(LTNode* phead)
{
	assert(phead);

	LTNode* pcur = phead->next;
	while (pcur != phead)
	{
		LTNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	//此时pcur指向phead,而phead还没有被销毁
	free(phead);
	phead = NULL;
} 

ps:LTDestroy参数理论上要传二级,因为我们需要让形参的改变影响到实参,但是为了保持接口一致性才传的一级。传一级存在的问题是,当形参phead置为NULL后,实参plist不会被修改为NULL,因此解决办法是:调用完方法后手动将实参置为NULL。

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

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

相关文章

Java如何获取当前日期和时间?

Java如何获取当前日期和时间? 本文将为您介绍 Java 中关于日期和时间获取的方法,以及介绍 Java 8 中获取日期和时间的全新API。 1、 System.currentTimeMillis() 获取标准时间可以使用 System.currentTimeMillis() 方法来获取,此方法优势是…

Qt与MySQL连接

QT连接Mysql数据库(详细成功版)-CSD N博客 我的MySQL是64位的,所以我的Qt的套件也需要是64位的 遇到的问题: (available drivers中已经有QMYSQL QMYSQL3,还是not loaded) QSqlDatabase: QMYS…

专项技能训练五《云计算网络技术与应用》实训7-1:安装mininet

文章目录 mininet安装1. 按6-1教程安装opendaylight控制器。2. 按6-2教程安装RYU控制器。3. 按5-1教程安装openvswitch虚拟交换机并开启服务。4. 将老师所给mininet安装包试用winSCP传送至电脑端。5. 安装net-tools。6. 安装mininet7. 安装完成后,使用命令建立拓扑&…

Jenkins集成Kubernetes 部署springboot项目

文章目录 准备部署的yml文件Harbor私服配置测试使用效果Jenkins远程调用参考文章 准备部署的yml文件 apiVersion: apps/v1 kind: Deployment metadata:namespace: testname: pipelinelabels:app: pipeline spec:replicas: 2selector:matchLabels:app: pipelinetemplate:metada…

腾讯云IM即时通信引入(React Web端组件式)

开发环境要求 React ≥ v18.0 (17.x 版本不支持) TypeScript node(12.13.0 ≤ node 版本 ≤ 17.0.0, 推荐使用 Node.js 官方 LTS 版本 16.17.0) npm(版本请与 node 版本匹配) chat-uikit-react 集成 …

软件工程习题答案2024最新版

习题一答案 一、选择题 软件的主要特性是(A B C)。 A) **无形 **B) 高成本 C) **包括程序和文档 ** D) 可独立构成计算机系统 软件工程三要素是(B)。 A) 技术、方法和工具 B) 方法、工具和过程 C) 方法、对象和类 D) 过程、模型、方法 包含风险分析的软件工程模型是(A)…

算法设计与分析——期末1h

目录 第一章 算法的定义 算法的三要素 算法的基本性质 算法的时间复杂度数量级: 第二章 兔子繁殖问题(递推法) 猴子吃桃问题(递推法) 穿越沙漠问题(递推法(倒推)) 百钱百…

Linux基础之yum和vim

目录 一、软件包管理器yum 1.1 软件包的概念 1.2 软件包的查看 1.3 软件包的安装和删除 二、Linux编辑器之vim 2.1 vim的基本概念 2.2 正常模式(命令模式) 2.3 底行模式 2.4 输入模式 2.5 替换模式 2.6 视图模式 2.7 总结 一、软件包管理器yu…

基于springboot+vue+Mysql的幼儿园管理系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

【Flask 系统教程 5】视图进阶

类视图 在 Flask 中,除了使用函数视图外,你还可以使用类视图来处理请求。类视图提供了一种更为结构化和面向对象的方式来编写视图函数,使得代码组织更清晰,并且提供了更多的灵活性和可扩展性。 创建类视图 要创建一个类视图&am…

Reactor模型详解

目录 1.概述 2.Single Reactor 3.muduo库的Multiple Reactors模型如下 1.概述 维基百科对Reactor模型的解释 The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs.…

办公数据分析利器:Excel与Power Query透视功能

数据分析利器:Excel与Power Query透视功能 Excel透视表和Power Query透视功能是强大的数据分析工具,它们使用户能够从大量数据中提取有意义的信息和趋势,可用于汇总、分析和可视化大量数据。 本文通过示例演示Power Query透视功能的一个小技…

【与 Apollo 共创生态:展望自动驾驶全新未来】

1、引言 历经七年的不懈追求与创新,Apollo开放平台已陆续推出了13个版本,汇聚了来自全球170多个国家与地区的16万名开发者及220多家合作伙伴。随着Apollo开放平台的不断创新与发展,Apollo在2024年4月19日迎来了Apollo开放平台的七周年大会&a…

43 单例模式

目录 1.什么是单例模式 2.什么是设计模式 3.特点 4.饿汉和懒汉 5.峨汉实现单例 6.懒汉实现单例 7.懒汉实现单例(线程安全) 8.STL容器是否线程安全 9.智能指针是否线程安全 10.其他常见的锁 11.读者写者问题 1. 什么是单例模式 单例模式是一种经典的&a…

保研面试408复习 1——操作系统、计网、计组

文章目录 1、操作系统一、操作系统的特点和功能二、中断和系统调用的区别 2、计算机组成原理一、冯诺依曼的三个要点二、MIPS(每秒百万条指令)三、CPU执行时间和CPI 3、计算机网络一、各个层常用协议二、网络协议实验——数据链路层a.网络速率表示b.数据…

机器学习的两种典型任务

机器学习中的典型任务类型可以分为分类任务(Classification)和回归任务(Regression) 分类任务 回归任务 简单的理解,分类任务是对离散值进行预测,根据每个样本的值/特征预测该样本属于类 型A、类型B 还是类…

迎接AI时代:智能科技的社会责任与未来展望

AI智能体的社会角色、伦理挑战与可持续发展路径 引言: 在技术的浪潮中,AI智能体正逐步成为我们生活的一部分。它们在医疗、教育、交通等领域的应用,预示着一个全新的时代即将到来。本文将结合实际案例和数据分析,深入探讨AI智能体…

JavaWeb请求响应概述

目录 一、请求响应流程-简述 二、深入探究 三、DispatcherServlet 四、请求响应流程-详细分析 一、请求响应流程-简述 web应用部署在tomcat服务器中,前端与后端通过http协议进行数据的请求和响应。前端通过http协议向后端发送数据请求,就可以访问到部…

Amazon EKS创建S3数据存储卷

亚马逊相关文档 1、创建适用于 Amazon S3的IAM策略 创建存储桶amazoneks {"Version": "2012-10-17","Statement": [{"Effect": "Allow","Action": "s3express:CreateSession","Resource": &…

docker部署nginx并配置https

1.准备SSL证书: 生成私钥:运行以下命令生成一个私钥文件。 生成证书请求(CSR):运行以下命令生成证书请求文件。 生成自签名证书:使用以下命令生成自签名证书。 openssl genrsa -out example.com.key 2048 …