当前位置: 首页 > news >正文

链表之双向链表的实现

铁汁们大家好,我们上一篇博客学习了单链表,这节课让我们继续往深学习,学习一下双线链表,话不多说,我们开始吧!



目录

1.双向链表

2.顺序表和链表的优缺点

3.双向链表的实现


1.双向链表

1.我们要实现的双线链表是带头双向循环链表,它的结构最复杂,一般用在单独的存储数据。我们实际中使用的链表数据结构都是带头双向循环链表。

2.它虽然结构复杂,但是在我们用代码实现过程中,它比单链表简单。

3.相信很多铁汁不清楚双向链表的结构是什么,如下图:

2.顺序表和链表的优缺点

我们在这里总结一下这两种线性表,方便之后的学习。

顺序表:

优点:空间连续,支持随机访问

缺点:中间或前面部分的插入和删除,时间复杂度是O(n);

           增容很不方便,代价较大。

链表:

优点:任意位置的插入删除,时间复杂度为O(1);

           没有增容销耗,按需申请节点空间,不用了直接释放。

缺点:以节点为单位存储,不支持随机访问

3.双向链表的实现

经过上面的铺垫,我们来实现一个带头双向循环链表

List.h文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int ADataType;
typedef struct ListNode
{ADataType data;struct ListNode* prev;//双线链表前驱指针struct ListNode* next;//后继指针
}LN;//双向链表初始化
LN* ListInit();
//为节点开辟空间
LN* BuyListCapacity(ADataType x);
//链表的销毁
void ListDestory(LN* phead);
//头插
void ListPushFront(LN* phead, ADataType x);
//尾插
void ListPushBack(LN* phead, ADataType x);
//打印
void ListPrint(LN* phead);
//头删
void ListPopFront(LN* phead);
//尾删
void ListPopBack(LN* phead);
//查找链表中的数据
LN* ListSearch(LN* phead, ADataType x);
//修改找到的数据
void ListModify( LN* pos, ADataType y);
//在这个位置后插入数据
void ListInsert(LN* pos, ADataType x);
//删除这个位置之后的数据
void ListErase(LN* pos);
//判断链表是否为空
bool ListEmpty(LN* phead);

List.c文件

#include"List.h"//为节点开辟空间
LN* BuyListCapacity(ADataType x)
{LN* newnode = (LN*)malloc(sizeof(LN));if (newnode == NULL){perror("malloc is false!\n");exit(-1);}newnode->data = x;newnode->next = NULL;newnode->prev = NULL;return newnode;
}//双向链表初始化
LN* ListInit()
{//开辟空间LN* phead = BuyListCapacity(0);//让头节点的前驱和后继都指向自己,是一个循环phead->next = phead;phead->prev = phead;return phead;
}//链表的销毁
void ListDestory(LN* phead)
{assert(phead);LN* tail = phead->next;while (tail != phead)//链表的头尾相连,当尾等于头时,说明链表空了{LN* next = tail->next;free(tail);tail = next;}free(phead);phead = NULL;
}
//头插
void ListPushFront(LN* phead, ADataType x)
{assert(phead);LN* newnode = BuyListCapacity(x);//若这里不使用新的变量来存储原来第一个节点的值,就先链接后,在链接前newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode;newnode->prev = phead;
}
//尾插
void ListPushBack(LN* phead, ADataType x)
{assert(phead);LN* newnode = BuyListCapacity(x);//找到尾,进行插入节点LN* tail = phead->prev;tail->next = newnode;newnode->prev = tail;phead->prev = newnode;newnode->next = phead;
}
//打印
void ListPrint(LN* phead)
{assert(phead);LN* tail = phead->next;while (tail != phead){printf(" %d ", tail->data);tail = tail->next;}printf("\n");
}
//头删
void ListPopFront(LN* phead)
{assert(phead);//判断链表是否为空,为空则删不了if (phead->next == phead){printf("List is NULL!\n");return;}//先记录下后一个节点LN* first = phead->next;LN* second = first->next;phead->next = second;second->prev = phead;free(first);first = NULL;
}
//尾删
void ListPopBack(LN* phead)
{assert(phead);//判断链表是否为空if (phead->prev == phead){printf("List is NULL!\n");return;}LN* tail = phead->prev;LN* prev = tail->prev;prev->next = phead;phead->prev = prev;free(tail);tail = NULL;
}
//查找链表中的数据
LN* ListSearch(LN* phead, ADataType x)
{assert(phead);LN* cur = phead->next;while (cur->data != x){cur = cur->next;}if (cur->data == x){return cur;}return NULL;
}
//修改找到的数据
void ListModify( LN* pos, ADataType y)
{assert(pos);pos->data = y;
}
//在这个位置后插入数据
void ListInsert(LN* pos, ADataType x)
{assert(pos);LN* newnode = BuyListCapacity(x);LN* next = pos->next;pos->next = newnode;newnode->prev = pos;newnode->next = next;next->prev = newnode;
}
//删除这个位置之后的数据
void ListErase(LN* pos)
{assert(pos);LN* cur = pos->next;LN* next = cur->next;pos->next = next;next->prev = pos;free(cur);cur = NULL;
}
//判断链表是否为空
bool ListEmpty(LN* phead)
{assert(phead);if (phead->prev == phead || phead->next == phead){return true;}return false;
}

Test.c文件

#include"List.h"
//带头双向循环链表的实现void Test1()
{LN* head = ListInit();ListPushFront(head, 33);ListPushFront(head, 22);ListPushFront(head, 11);ListPushBack(head, 4);ListPushBack(head, 5);ListPushBack(head, 6);ListPushBack(head, 7);ListPushBack(head, 8);ListPushBack(head, 9);ListPushBack(head, 10);printf("ListNode:> ");ListPrint(head);ListPopFront(head);ListPopBack(head);printf("ListNode:> ");ListPrint(head);LN* pos = ListSearch(head, 7);if (pos == NULL){printf("Not Find!\n");}else{printf("the number is %d\n", pos->data);ListModify(pos, 77);printf("ListNode:> ");ListPrint(head);ListInsert(pos, 13);ListInsert(pos, 14);ListInsert(pos, 15);printf("ListNode:> ");ListPrint(head);ListErase(pos);printf("ListNode:> ");ListPrint(head);}if (ListEmpty(head)){printf("List is NULL!\n");}else{printf("List is Notnull!\n");}ListDestory(head);printf("List is disory!\n");
}int main()
{Test1();return 0;
}

结果:结果就是这样的,大家可以自己尝试一下!


这就是双向链表的实现,大家还是要自己敲一遍代码,帮助自己更好的掌握知识点。

谢谢铁汁们的支持,咱们下期再见!!!

相关文章:

链表之双向链表的实现

铁汁们大家好&#xff0c;我们上一篇博客学习了单链表&#xff0c;这节课让我们继续往深学习&#xff0c;学习一下双线链表&#xff0c;话不多说&#xff0c;我们开始吧&#xff01; 目录 1.双向链表 2.顺序表和链表的优缺点 3.双向链表的实现 1.双向链表 1.我们要实现的双线…...

小白学大模型:什么是生成式人工智能?

什么是生成式人工智能&#xff1f; 在过去几年中&#xff0c;机器学习领域取得了迅猛进步&#xff0c;创造了人工智能的一个新的子领域&#xff1a;生成式人工智能。这些程序通过分析大量的数字化材料产生新颖的文本、图像、音乐和软件&#xff0c;我将这些程序简称为“GAIs”…...

并发编程01-深入理解Java并发/线程等待/通知机制

为什么我们要学习并发编程&#xff1f; 最直白的原因&#xff0c;因为面试需要&#xff0c;我们来看看美团和阿里对 Java 岗位的 JD&#xff1a; 从上面两大互联网公司的招聘需求可以看到&#xff0c; 大厂的 Java 岗的并发编程能力属于标配。 而在非大厂的公司&#xff0c; 并…...

3.类与对象(中篇)介绍了类的6个默认构造函数,列举了相关案例,实现了一个日期类

1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会…...

Vue实现手机APP页面的切换,如何使用Vue Router进行路由管理呢?

在Vue中&#xff0c;实现手机APP页面的切换&#xff0c;通常会使用Vue Router进行路由管理。Vue Router是Vue.js官方的路由管理器&#xff0c;它和Vue.js深度集成&#xff0c;使构建单页面应用变得易如反掌。 以下是一个简单的步骤说明&#xff0c;展示如何使用Vue Router实现…...

软考--软件设计师(软件工程总结2)

目录 1.测试方法 2.软件项目管理 3.软件容错技术 4.软件复杂性度量 5.结构化分析方法&#xff08;一种面向数据流的开发方法&#xff09; 6.数据流图 1.测试方法 软件测试&#xff1a;静态测试&#xff08;被测程序采用人工检测&#xff0c;计算机辅助静态分析的手段&…...

渗透测试之SSRF漏洞

一、SSRF介绍 SSRF&#xff08;Cross-site Scripting&#xff0c;简称XSS&#xff09;是一种安全漏洞&#xff0c;它允许攻击者通过构造特定的请求&#xff0c;使服务器发起对外网无法访问的内部系统请求。这种漏洞通常发生在服务端提供了从其他服务器应用获取数据的功能&#…...

【C++】1957. 求三个数的平均数

问题&#xff1a;1957. 求三个数的平均数 类型&#xff1a;基本运算、小数运算 题目描述&#xff1a; 小雅刚刚考完语文、数学、英语的三门期中考试&#xff0c;她想请你编个程序来帮她算算她的平均分。 要求输入三个正整数&#xff0c;分别表示三科考试的分数&#xff0c;输…...

GPU部署ChatGLM3

首先&#xff0c;检查一下自己的电脑有没有CUDA环境&#xff0c;没有的话&#xff0c;去安装一个。我的电脑是4060显卡&#xff0c;买回来就自带这些环境了。没有显卡的话&#xff0c;也不要紧&#xff0c;这个懒人安装包支持CPU运行&#xff0c;会自动识别没有GPU&#xff0c;…...

Windows远程执行

Windows远程执行 前言 1、在办公环境中&#xff0c;利用系统本身的远程服务进行远程代码执行甚至内网穿透横向移动的安全事件是非常可怕的&#xff0c;因此系统本身的一些远程服务在没有必要的情况下建议关闭&#xff0c;防止意外发生&#xff1b; 2、作为安全人员&#xff0…...

AJAX —— 学习(一)

目录 一、原生 AJAX &#xff08;一&#xff09;AJAX 介绍 1.理解 2.作用 3.最大的优势 4.应用例子 &#xff08;二&#xff09;XML 介绍 1.理解 2.作用 &#xff08;三&#xff09;AJAX 的特点 1.优点 2.缺点 二、HTTP 协议 &#xff08;一&#xff09;HTTP 介…...

Activity——idea(2020以后)配置actiBPM

文章目录 前言jar下载idea 安装本地扩展插件 前言 2020及之后版本的idea中&#xff0c;未维护对应的actiBPM扩展插件。如果需要安装该插件&#xff0c;则需要使用本地导入 jar的方式。 jar下载 访问官方网站&#xff0c;搜索对应的actiBPM扩展插件。 https://plugins.jetbra…...

MyBatis——配置优化和分页插件

MyBatis配置优化 MyBatis配置文件的元素结构如下&#xff1a; configuration&#xff08;配置&#xff09; properties&#xff08;属性&#xff09; settings&#xff08;设置&#xff09; typeAliases&#xff08;类型别名&#xff09; plugins&#xff08;插件&#xff09…...

[蓝桥杯 2013 省 B] 翻硬币

[蓝桥杯 2013 省 B] 翻硬币 题目背景 小明正在玩一个“翻硬币”的游戏。 题目描述 桌上放着排成一排的若干硬币。我们用 * 表示正面&#xff0c;用 o 表示反面&#xff08;是小写字母&#xff0c;不是零&#xff09;&#xff0c;比如可能情形是 **oo***oooo&#xff0c;如果…...

[BT]BUUCTF刷题第13天(4.1)

第13天 Upload-Labs-Linux (Basic) Pass-01 根据题目提示&#xff0c;该题为绕过js验证。 一句话木马&#xff1a; <?php eval(system($_POST["cmd"]));?> // 符号 表示后面的语句即使执行错误&#xff0c;也不报错。 // eval() 把括号内的字符串全部…...

特别详细的Spring Cloud 系列教程1:服务注册中心Eureka的启动

Eureka已经被Spring Cloud继承在其子项目spring-cloud-netflix中&#xff0c;搭建Eureka Server的方式还是非常简单的。只需要通过一个独立的maven工程即可搭建Eureka Server。 我们引入spring cloud的依赖和eureka的依赖。 <dependencyManagement><!-- spring clo…...

Day108:代码审计-PHP模型开发篇MVC层动态调试未授权脆弱鉴权未引用错误逻辑

目录 案例1-Xhcms-动态调试-脆弱的鉴权逻辑 案例2-Cwcms-动态调试-未引用鉴权逻辑 案例3-Bosscms-动态调试-不严谨的鉴权逻辑 知识点&#xff1a; 1、PHP审计-动态调试-未授权安全 2、PHP审计-文件对比-未授权安全 3、PHP审计-未授权访问-三种形态 动态调试优点: 环境配置&…...

重读Java设计模式: 桥接模式详解

引言 在软件开发中&#xff0c;经常会遇到需要在抽象与实现之间建立连接的情况。当系统需要支持多个维度的变化时&#xff0c;使用传统的继承方式往往会导致类爆炸和耦合度增加的问题。为了解决这一问题&#xff0c;我们可以使用桥接模式。桥接模式是一种结构型设计模式&#…...

新规解读 | 被网信办豁免数据出境申报义务的企业,还需要做什么?

为了促进数据依法有序自由流动&#xff0c;激发数据要素价值&#xff0c;扩大高水平对外开放&#xff0c;《促进和规范数据跨境流动规定》&#xff08;以下简称《规定》&#xff09;对数据出境安全评估、个人信息出境标准合同、个人信息保护认证等数据出境制度作出优化调整。 …...

fakebook-攻防世界

题目 先目录扫描一下 dirseach 打开flag.php是空白的 访问robots.txt,访问user.php.bak <?php class UserInfo { public $name ""; public $age 0; public $blog ""; public function __construct($name, $age, $blog) { …...

从NUCLEO板载调试器到独立ST-LINK:打造高效STM32开发环境

1. 为什么需要独立ST-LINK调试器&#xff1f; 很多STM32开发者刚开始接触NUCLEO开发板时&#xff0c;都会发现板子上自带了一个ST-LINK调试器。这个设计本来是为了方便初学者快速上手&#xff0c;但随着项目复杂度提升&#xff0c;你会发现这个板载调试器存在不少限制。比如每次…...

MCUXPresso for VS Code插件实战:从零构建NXP MCU的HelloWorld项目

1. 项目概述&#xff1a;为什么选择MCUXPresso for VS Code&#xff1f;如果你是一位嵌入式开发者&#xff0c;尤其是使用恩智浦&#xff08;NXP&#xff09;MCU的工程师&#xff0c;那么你大概率对MCUXpresso IDE不陌生。它是一个功能强大的集成开发环境&#xff0c;但有时我们…...

Qt实战:手把手教你优化QCustomPlot曲线图,解决坐标轴覆盖数据点的坑

Qt实战&#xff1a;深度优化QCustomPlot曲线图显示效果 在Qt应用开发中&#xff0c;数据可视化是提升用户体验的关键环节。QCustomPlot作为Qt生态中最受欢迎的2D绘图库之一&#xff0c;以其轻量级和高性能著称&#xff0c;被广泛应用于工业控制、科学研究和金融分析等领域。然而…...

通过ip命令配置网络地址的方法

cat ../ip_cfg.sh # 为 end1 接口添加一个静态 IP 地址 (例如: 192.168.1.100/24) sudo ip addr add 196.12.0.100/24 dev end1# 激活 end1 接口 sudo ip link set end1 up# &#xff08;可选&#xff09;添加默认网关&#xff0c;例如 192.168.1.1 sudo ip route add default …...

别再浪费主板上的PCIE插槽了!手把手教你用VL805芯片打造高速USB3.0扩展坞

释放主板潜能&#xff1a;基于VL805芯片的USB3.0扩展方案实战指南 当你的工作台摆满外设却苦于主板接口不足时&#xff0c;那些闲置的PCIE插槽正等待被唤醒。本文将从芯片选型到性能调优&#xff0c;完整呈现如何将一块VL805-QFN68芯片转化为高性能USB3.0扩展方案。 1. 硬件选型…...

如何高效下载B站视频:BiliDownloader终极使用教程

如何高效下载B站视频&#xff1a;BiliDownloader终极使用教程 【免费下载链接】BiliDownloader BiliDownloader是一款界面精简&#xff0c;操作简单且高速下载的b站下载器 项目地址: https://gitcode.com/gh_mirrors/bi/BiliDownloader 想要轻松保存B站上的精彩视频内容…...

【免费下载】 探索高效Excel处理:OpenXLSX C++读写Excel表格示例项目推荐

探索高效Excel处理&#xff1a;OpenXLSX C读写Excel表格示例项目推荐 项目介绍 在现代软件开发中&#xff0c;处理Excel文件的需求日益增长&#xff0c;尤其是在数据分析、报告生成和企业级应用中。为了满足这一需求&#xff0c;我们推出了OpenXLSX C读写Excel表格示例项目。该…...

ComfyUI Segment Anything 终极指南:一键实现精准AI图像分割

ComfyUI Segment Anything 终极指南&#xff1a;一键实现精准AI图像分割 【免费下载链接】comfyui_segment_anything Based on GroundingDino and SAM, use semantic strings to segment any element in an image. The comfyui version of sd-webui-segment-anything. 项目地…...

2023B卷,跳格子(1)

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:华为OD面试 文章目录 一、🍀前言 1.1 ☘️题目详情 1.2 ☘️参考解题答案 一、🍀前言 2023B卷,跳格子(1) 。 1.1 ☘️题目详情 题目: 小明和朋友…...

突发外交事件3分钟响应!Perplexity国际新闻搜索应急配置清单,含12条预设Prompt与可信度评分模型

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;突发外交事件3分钟响应&#xff01;Perplexity国际新闻搜索应急配置清单&#xff0c;含12条预设Prompt与可信度评分模型 面对突发外交事件&#xff08;如边境冲突升级、高层会谈临时取消、制裁公告突袭发布&am…...