【零基础学数据结构】双向链表

news2024/12/22 19:35:09

1.双向链表的概念

1.1头节点 

 1.2带头双向循环链表

注意: 哨兵位创建后,首尾连接自己

1.3双链表的初始化

// 双向链表的初始化
void ListInit(ListNode** pphead)
{
	// 给双链表创建一个哨兵位
	*pphead = ListBuyNode(-1);
}

2.双向链表的打印 

// 双向链表的打印
void ListPrint(ListNode* phead)
{
	// 遍历链表
	ListNode* pcur = phead->next;
	while (pcur != phead)
	{
		// 打印
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("\n");
}

 3.双向链表的尾插 

// 双向链表的尾插
void ListPushBack(ListNode* phead, ListDatatype x)
{
	// 创建一个存放数据的新节点
	ListNode* newnode = ListBuyNode(x);

	// 进行尾插
	// 新节点连接
	newnode->prev = phead->prev;
	newnode->next = phead;

	// 改变原来链表的连接
	phead->prev->next = newnode;
	phead->prev = newnode;
}

4.双向链表的头插 

void ListPushFront(ListNode* phead, ListDatatype x)
{
	// 创建一个存放数据的新节点
	ListNode* newnode = ListBuyNode(x);

	// 进行头插
	// 新节点连接
	newnode->prev = phead;
	newnode->next = phead->next;

	// 改变原来链表的连接
	phead->next->prev = newnode;
	phead->next = newnode;
}

5.双向链表的尾删 

void ListPopBack(ListNode* phead)
{
	assert(phead && phead->next != phead);

	// 进行尾删除
	ListNode* del = phead->prev;
	del->prev->next = del->next; 
	del->next->prev = del->prev;

	// 释放空间
	free(del);
	del = NULL;
}

6.双向链表的头删 

void ListPopFront(ListNode* phead)
{
	assert(phead && phead->next != phead);

	// 进行头删除
	ListNode* del = phead->next;
	del->next->prev = phead;
	phead->next = del->next;

	// 释放空间
	free(del);
	del = NULL;
}

7.双向链表的查找  

ListNode* ListFind(ListNode* phead, ListDatatype x)
{
	// 遍历双向链表
	ListNode* pcur = phead->next;
	while (pcur != phead)
	{
		// 打印
		if (pcur->data == x)
		{
			return pcur;
		}
		pcur = pcur->next;
	}

	// 没有找到
	return NULL;
}

 8.双向链表在pos位置之后插入 

void ListInsret(ListNode* pos, ListDatatype x)
{
	assert(pos);

	// 创建一个存放数据的新节点
	ListNode* newnode = ListBuyNode(x);

	// 插入
	// 新节点连接
	newnode->prev = pos;
	newnode->next = pos->next;

	// 原链表连接
	pos->next->prev = newnode;
	pos->next = newnode;
}

9.双向链表删除pos节点 

void ListErase(ListNode* pos)
{
	//pos理论上来说不能为phead,但是没有参数phead,无法增加校验
	assert(pos);

	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;

	free(pos);
	pos = NULL;
}

 10.双向链表的销毁

void ListDesTroy(ListNode* phead)
{
	assert(phead);

	// 遍历删除
	ListNode* pcur = phead->next;
	while (pcur != phead)
	{
		ListNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	//此时pcur指向phead,而phead还没有被销毁
	free(phead);
	phead = NULL;
	printf("销毁成功!");
}

 测试文件:

#include "List.h"

void ListNodetext()
{
	ListNode* plist;
	ListInit(&plist);

	// 测试尾插
	ListPushBack(plist, 1);
	/*ListPrint(plist);*/
	ListPushBack(plist, 2);
	/*ListPrint(plist);*/
	ListPushBack(plist, 3);
	ListPrint(plist); // 1->2->3->

	// 测试头插
	//ListPushFront(plist, 6);
	//ListPrint(plist);
	//ListPushFront(plist, 7);
	//ListPrint(plist);
	//ListPushFront(plist, 8);
	//ListPrint(plist);

	// 测试尾删
	//ListPopBack(plist);
	//ListPrint(plist);
	//ListPopBack(plist);
	//ListPrint(plist);
	//ListPopBack(plist);
	//ListPrint(plist);

	// 测试头删
	//ListPopFront(plist);
	//ListPrint(plist);
	//ListPopFront(plist);
	//ListPrint(plist);
	//ListPopFront(plist);
	//ListPrint(plist);

	// 测试查找
	//ListNode* find = ListFind(plist, 30);
	//if (find == NULL)
	//{
	//	printf("没有找到!");
	//}
	//else
	//{
	//	printf("找到了!");
	//}

	// 测试pos位置之后插入
	//ListNode* find = ListFind(plist, 2);
	//ListInsret(find, 5);
	//ListPrint(plist);

	// 测试删除pos节点
	//ListNode* find = ListFind(plist, 3);
	//ListErase(find);
	//find = NULL;
	//ListPrint(plist);

	ListDesTroy(plist);
	plist = NULL;
}

int main()
{
	ListNodetext();
	return 0;
}

 

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

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

相关文章

PE文件的分析和构造超详细过程

本文详细讲述如何从0构造一个PE文件,运行该文件会弹出一个HelloPE的窗口 目录 预备知识 1. 构造DOS头IMAGE_DOS_HEADER 1.1 构造DOS_MZ头 1.2 构造DOS_STUB 2、构造PE头IMAGE_NT_HEADERS 248字节 2.1 signature 2.2 IMAGE_FILE_HEADER 2.3 IMAGE_OPTI…

MOS管电路的应用及注意事项

1,buck电路的上下桥死区时间多少合适 死区时间由驱动芯片控制的,外围电路增加阻容会导致上升沿时间变长 死区时间从单片机PWM到驱动电路再到MOS管的栅极都有一定的硬件延时,所以具体时间需要根据调试确定。 例如充电芯片的buck电路,有死区配置…

mysql8.0高可用集群架构实战

MySQL :: MySQL Shell 8.0 :: 7 MySQL InnoDB Cluster 基本概述 InnoDB Cluster是MySQL官方实现高可用读写分离的架构方案,其中包含以下组件 MySQL Group Replication,简称MGR,是MySQL的主从同步高可用方案,包括数据同步及角色选举Mysql Shell 是InnoDB Cluster的管理工具,用…

数据库系统概论(超详解!!!)第四节 数据库安全性

问题的提出: 数据库的一大特点是数据可以共享 数据共享必然带来数据库的安全性问题 数据库系统中的数据共享不能是无条件的共享。 1.数据库的安全概述 数据库的安全性是指保护数据库以防止不合法使用所造成的数据泄露、更改或破坏 。 系统安全保护措施是否有效…

基于ssm的土家风景文化管理平台(java源码+文档)

项目简介 土家风景文化管理平台实现了以下功能: 土家风景文化管理平台的主要使用者分为管理员:管理员使用本平台涉到的功能主要有:首页,个人中心,用户管理,景点分类管理,热门景点管理&#xf…

深度学习学习日记4.7

1.梯度下降 w 新 w旧 - 学习率梯度 训练的目的就是让 loss 减小 2.前向传播进行预测, 反向传播进行训练(每一个参数通过梯度下降进行更新参数),(1前向传播 2求 loss 3反向传播 4梯度更新) 能够让损失下降的参数,就是更好的参数。 损失…

基于SSM物业管理系统

摘要 进入二十一世纪以来,计算机技术蓬勃发展,人们的生活发生了许多变化。很多时候人们不需要亲力亲为的做一些事情,通过网络即可完成以往需要花费很多时间的操作,这可以提升人们的生活质量。计算机技术对人们生活的改变不仅仅包…

单列模式1.0

单列模式 单例模式能保证某个类在程序中只存在唯⼀⼀份实例, ⽽不会创建出多个实例 1.饿汉模式 只要程序一启动就会立即创建出一个对象 class Signleton{private static Signleton instancenew Signleton();//防止在以后的代码中再创建对象,我们将构造方法private,…

FreeFileSync|本地自动备份设置教程,终于可以不用手动同步了

前言 昨天小白给各位小伙伴分享了FreeFileSync软件,由于篇幅过长,所以整个教程中并没有教小伙伴们如何设置自动同步的办法。 今天小白就来唠唠:如何让FreeFileSync自动同步。 教程分为几种: 开机自动同步 开机之后自动执行一次…

LeetCode617:合并二叉树

题目描述 给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重…

天地人和•大道不孤——卢禹舜中国画作品展在重庆美术馆隆重开幕

2024年4月12日,由中国国家画院、重庆市文化和旅游发展委员会主办,重庆美术馆(重庆画院、重庆国画院)、北京八荒锦绣美术馆、中国国际文化交流基金会卢禹舜艺术基金承办的“天地人和•大道不孤——卢禹舜中国画作品展”开幕式在重庆…

SF58-ASEMI适配器二极管SF58

编辑:ll SF58-ASEMI适配器二极管SF58 型号:SF58 品牌:ASEMI 封装:DO-27 最大平均正向电流(IF):5A 最大循环峰值反向电压(VRRM):600V 最大正向电压&…

C语言函数指针应用——计算器(转移表)的使用

对与上一节,我们对指针函数已经有了深刻意识了;练一练吧 如果还没有学习到,也是没有关系的,可以看一看这一篇 C语言详解指针-CSDN博客https://blog.csdn.net/Asuku_/article/details/137690083希望能提高你对指针的理解 计算器的实…

使用Riverpod在Flutter中创建Todo列表

使用Riverpod在Flutter中创建Todo列表 视频 https://youtu.be/mlbeSD1KSIo https://www.bilibili.com/video/BV1jj42197c8/ 前言 原文 https://ducafecat.com/blog/flutter-todo-list-with-riverpod-guide-02 学习如何使用Riverpod在Flutter中构建一个功能完整的Todo列表应用…

《AI创业浪潮:展望未来,解锁颠覆性创新机遇》

在科技革命的浪潮中,人工智能(AI)犹如一艘引领航向的旗舰,以其强大的变革力量重塑各行各业。随着技术的日益成熟与应用场景的不断拓宽,AI技术为创业者铺就了一条充满机遇与挑战的道路。本文将深入探讨未来AI技术领域的…

CPU问题排查

经常发现生产环境CPU运行很高,我们想知道到底是什么代码这么消耗CPU TOP命令 此时我们经常使用top来找到 CPU 使用率比较高的一些线程 容器中的docker 备注: 如果是docker 中的top命令。需要关注,一般来说不需要,挂载内容的多…

TSINGSEE青犀AI智能分析网关V4叉车载货出入库检测算法介绍及应用

随着物流行业的快速发展,叉车作为物流运输的重要设备,其安全性和效率性越来越受到人们的关注。然而,在实际操作中,由于人为因素和操作环境的复杂性,叉车事故时有发生,给企业和个人带来了巨大的损失。为了提…

cbv源码

cbv源码 【1】什么是查找顺序 对象属性的查找顺序: 首先在对象自身的命名空间(属性字典)中查找属性。如果在对象自身的命名空间中没有找到,则会向上查找该对象的类(class)的命名空间,直到找到…

mysql索引与优化问题

作为一个java程序员,mysql数据库面试应该是比较多的了;而关于数据库的面试,最多的就是性能问题,而以性能为起点,延伸出很多具体的问题。 我们使用第一性原理的方法来分析,为什么面试中一定会问数据库的索引…

vox2vec论文速读

vox2vec: A Framework for Self-supervised Contrastive Learning of Voxel-Level Representations in Medical Images 摘要 本文介绍了 vox2vec——一种体素级表示的自监督学习 (SSL) 对比方法 vox2vec 表示由特征金字塔网络 (FPN&#xf…