【C语言|数据结构】双向链表

文章目录

    • 前言
    • 1、初步认识双向链表
        • 1.1 定义:
        • 1.2 结构
        • 1.3 节点的存储
    • 2、双向链表的接口函数
        • 2.1 链表的节点的动态申请
        • 2.2 链表的初始化
        • 2.3 尾插
        • 2.4 头插
        • 2.5 头删
        • 2.5 尾删
        • 2.6 在pos节点后面添加数据
        • 2.6 删除pos节点
    • 3、双向链表的实现:

前言

各位小伙伴大家好,即上回的单向链表之后,双向链表来了,他和单向链表的主要区别就是,他有两个指针,同时指向前面一个节点,和后面一个节点,简直是完美,几乎解决的单向链表的大多数难题

1、初步认识双向链表

1.1 定义:

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向前面一个节点和后面一个节点。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

1.2 结构

在这里插入图片描述

这是带头的双向循环链表。

1.3 节点的存储
typedef int DLDataType;typedef struct LinkNode
{DLDataType data;struct LinkNode* next;struct LinkNode* prv;
}LNode;

2、双向链表的接口函数

2.1 链表的节点的动态申请
LTNode* LTFound(DLDataType x)
{LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));if (newNode == NULL){perror("LTInit()::malloc()");return;}newNode->next = newNode->prv = newNode;newNode->data = x;return newNode;
}
2.2 链表的初始化
// 法一:
LTNode* LTInit()
{LTNode* newhead = LTFound(-1);return newhead;
}
法二:
void LTInit(LTNode** pphead)
{LTNode* newhead = LTFound(-1);*phead = newhead;
}
2.3 尾插
void LTPushBack(LTNode* phead, DLDataType x)
{assert(phead);LTNode* cmp = LTFound(x);// phead phead->prv cmpcmp->next = phead;cmp->prv = phead->prv;phead->prv->next = cmp;phead->prv = cmp;
}

尾插这个节点不管是插入在头节点的前面还是尾节点后面都是一样的

2.4 头插
//头插
void LTPushFront(LTNode* phead, DLDataType x)
{assert(phead);LTNode* tmp = LTFound(x);// phead tmp phead->nexttmp->next = phead->next;tmp->prv = phead;phead->next = tmp;phead->next->prv = tmp;
}

头插必须插入在头节点的后面才是头插,头节点就是哨兵卫,链表进行操作的时候不能操作哨兵卫,否则就不带头了。

2.5 头删
//头删
void LTPopFront(LTNode* phead)
{assert(phead && phead->next != phead);LTNode* cur = phead->next;// phead  cur cur->nextphead->next = cur->next;cur->next = phead;free(cur);cur = NULL;
}
2.5 尾删
//尾删
void LTPopBack(LTNode* phead)
{assert(phead && phead->next != phead);LTNode* cur = phead->prv;// phead cur->prv curphead->prv = cur->prv;cur->prv->next = phead;free(cur);cur = NULL;
}
2.6 在pos节点后面添加数据
//在pos位置之后插入数据
void LTInsert(LTNode* pos, DLDataType x)
{assert(pos);LTNode* cur = LTCreate(x);// pos cur pos->nextcur->next = pos->next;cur->prv = pos;pos->next = cur;pos->next->prv = cur;}
2.6 删除pos节点
//删除pos节点
void LTErase(LTNode* pos)
{assert(pos);// pos->prv pos pos->nextpos->prv->next = pos->next;pos->next->prv = pos->prv;free(pos);pos = NULL;
}

3、双向链表的实现:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <string.h>typedef int DLDataType;typedef struct LinkNode
{DLDataType data;struct LinkNode* next;struct LinkNode* prv;
}LTNode;//双链表的节点创建
LTNode* LTCreate(DLDataType x)
{LTNode* newNode = (LTNode*)malloc(sizeof(LTNode));if (newNode == NULL){perror("LTInit()::malloc()");exit(-1);}newNode->next = newNode;newNode->prv = newNode;newNode->data = x;return newNode;
}//初始化
//void LTInit(LTNode** pphead)
//{
//	LTNode* newhead = LTFound(-1);
//}LTNode* LTInit()
{LTNode* newhead = LTCreate(-1);return newhead;
}//销毁链表
void LTDesTroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}free(phead);phead = NULL;
}//链表的打印
void LTPrint(LTNode* phead)
{LTNode* cur = phead->next;while (cur != phead){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");
}//查找pos节点
LTNode* LTFind(LTNode* phead, DLDataType x)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}//插入数据之前,链表必须初始化到只有一个头结点的情况
//不改变哨兵位的地址,因此传一级即可
//尾插
void LTPushBack(LTNode* phead, DLDataType x)
{assert(phead);LTNode* cmp = LTCreate(x);// phead phead->prv cmpcmp->next = phead;cmp->prv = phead->prv;phead->prv->next = cmp;phead->prv = cmp;
}//头插
void LTPushFront(LTNode* phead, DLDataType x)
{assert(phead);LTNode* tmp = LTCreate(x);// phead tmp phead->nexttmp->next = phead->next;tmp->prv = phead;phead->next = tmp;phead->next->prv = tmp;
}//尾删
void LTPopBack(LTNode* phead)
{assert(phead && phead->next != phead);LTNode* cur = phead->prv;// phead cur->prv curphead->prv = cur->prv;cur->prv->next = phead;free(cur);cur = NULL;
}//头删
void LTPopFront(LTNode* phead)
{assert(phead && phead->next != phead);LTNode* cur = phead->next;// phead  cur cur->nextphead->next = cur->next;cur->next = phead;free(cur);cur = NULL;
}//在pos位置之后插入数据
void LTInsert(LTNode* pos, DLDataType x)
{assert(pos);LTNode* cur = LTCreate(x);// pos cur pos->nextcur->next = pos->next;cur->prv = pos;pos->next = cur;pos->next->prv = cur;}//删除pos节点
void LTErase(LTNode* pos)
{assert(pos);// pos->prv pos pos->nextpos->prv->next = pos->next;pos->next->prv = pos->prv;free(pos);pos = NULL;
}void DLinkListText()
{LTNode* phead = LTInit();LTPushBack(phead, 1);LTPushBack(phead, 2);LTPushBack(phead, 3);LTPrint(phead);LTPushFront(phead, 0);LTPushFront(phead, 999);LTPrint(phead);// LTPopFront(phead);// LTPrint(phead);LTPopBack(phead);LTPrint(phead);LTDesTroy(phead);
}int main()
{DLinkListText();return 0;
}

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

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

相关文章

C控制语句:分支和跳转

1.1if语句 //colddays.c --找出0摄氏度以下的天数占总天数的百分比 #include <stdio.h>int main(void) {const int FREEZING 0;float temperature;int cold_days 0;int all_days 0;printf("Enter the list of daily low temperature.\n");printf("Use…

电子学会C/C++编程等级考试2024年03月(八级)真题解析

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;道路 N个以 1 … N 标号的城市通过单向的道路相连:。每条道路包含两个参数&#xff1a;道路的长度和需要为该路付的通行费&#xff08;以金币的数目来表示&#xff09; Bob and Alice 过去住在城市 1.在…

蓝海创业商机小吃配方项目,日入200+ ,小白可上手,图文创作转现快

小吃技术销售&#xff0c;一单价格从几元到几百元不等&#xff0c;行业竞争相对较小&#xff0c;是一个相对冷门的领域。只需一部手机&#xff0c;就可以发布图文并茂的内容&#xff0c;配上背景音乐&#xff08;BGM&#xff09;&#xff0c;即使是对视频剪辑不熟悉的新手&…

面试中算法(金矿)

有一位国王拥有5座金矿&#xff0c;每座金矿的黄金储量不同&#xff0c;需要参与挖掘的工人人数也不同。 例如&#xff0c;有的金矿储量是5ookg黄金&#xff0c;需要5个工人来挖掘;有的金矿储量是2ookg黄金&#xff0c;需要3个工人来挖掘...... 如果参与挖矿的工人的总数是10。…

试衣不再有界:Tunnel Try-on开启视频试衣应用新纪元

论文&#xff1a;https://arxiv.org/pdf/2404.17571 主页&#xff1a;https://mengtingchen.github.io/tunnel-try-on-page/ 一、摘要总结 随着虚拟试衣技术的发展&#xff0c;消费者和时尚行业对于能够在视频中实现高质量虚拟试衣的需求日益增长。这项技术允许用户在不实际穿…

目标检测——印度车辆数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

区块链中的APP与传统APP的区别

一、技术 区块链中的APP是基于区块链技术开发的&#xff0c;而传统APP则基于传统的应用程序商店或网页。区块链中的APP利用区块链技术的去中心化、数据不可篡改等特点&#xff0c;使得应用程序的开发和分发更加安全、透明和可信。与传统APP相比&#xff0c;区块链中的APP无需中…

Web安全:SQL注入之布尔盲注原理+步骤+实战操作

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…

访客管理系统对于校园安全的重要性

校园访客办理计划是针对校园安全需求规划的安全办理体系&#xff0c;主要用于对校园外来人员的科学办理。要做好校园安全作业&#xff0c;把风险分子拒之门外尤为要害。校园访客办理计划实现访客实名制&#xff0c;并结合公安网、黑名单功用&#xff0c;对风险人员进行提前预警…

没有公网ip,如何实现外网访问内网?

目前拨号上网是最广泛的上网方式&#xff0c;这种方式优点是价格便宜&#xff0c;缺点是没有固定公网ip&#xff0c;每次重新您拨号ip地址都会变。如果有一台服务器&#xff0c;需要实现外网访问&#xff0c;在没有固定公网ip的环境下&#xff0c;该如何实现呢&#xff1f;使用…

【CTF Web】QSNCTF 文章管理系统 Writeup(SQL注入+Linux命令+RCE)

文章管理系统 题目描述 这是我们的文章管理系统&#xff0c;快来看看有什么漏洞可以拿到FLAG吧&#xff1f;注意&#xff1a;可能有个假FLAG哦 解法 SQL 注入。 ?id1 or 11 --取得假 flag。 爆库名。 ?id1 union select 1,group_concat(schema_name) from information_sch…

华为OD机试【统一限载货物数最小值】(java)(200分)

1、题目描述 火车站附近的货物中转站负责将到站货物运往仓库&#xff0c;小明在中转站负责调度 2K 辆中转车(K辆干货中转车&#xff0c;K 辆湿货中转车)货物由不同供货商从各地发来&#xff0c;各地的货物是依次进站&#xff0c;然后小明按照卸货顺序依次装货到中转车&#xf…

二维数组 和 变长数组

在上一期的内容中&#xff0c;为诸君讲解到了一维数组&#xff0c;在一维数组的基础上&#xff0c;C语言中还有着多维数组&#xff0c;其中&#xff0c;比较典型且运用较为广泛的就是我们今天的主角——二维数组 一 . 二维数组的概念 我们把单个或者多个元素组成的数组定义为一…

VScode 修改 Markdown Preview Enhanced 主题与字体

VScode 修改 Markdown Preview Enhanced 主题与字体 1. 修改前后效果对比2. 修改主题2.1 更改默认主题2.2 修改背景色 3. 修改字体 VS Code基础入门使用可查看&#xff1a; VS Code 基础入门使用&#xff08;配置&#xff09;教程 其他Vs Code 配置可关注查看&#xff1a; Vs C…

2024年如何选什么版本FL Studio才适合自己编曲?

fl studio是什么软件 水果编曲软件 FL Studio&#xff0c;全称为Fruity Loops Studio&#xff0c;是一款全能音乐制作环境或数字音频工作站&#xff08;DAW&#xff09;&#xff0c;集编曲、录音、剪辑、混音等多种功能于一身。 FL Studio最初名为Fruity Loops&#xff0c;因…

外网如何访问内网?快解析

由于公网IP资源短缺&#xff0c;我们的电脑大多处于内网环境&#xff0c;如何在外网访问内网电脑&#xff0c;成为一个令人头疼的问题&#xff0c;下面我给大家推荐一个非常实用的方法。 1&#xff1a;访问快解析下载安装快解析服务器 2&#xff1a;运行软件&#xff0c;点击“…

2.4 输入和显示

本节必须掌握的知识点&#xff1a; 示例五源代码 代码分析 汇编解析 2.4.1 示例五 ■格式化输入函数scanf scanf函数可以从键盘读取输入的信息。scanf函数同样可以像printf函数那样&#xff0c;通过转换说明“%d”来限制函数只能读取十进制数。scanf函数的参数为可变参数…

LwIP 之九 详解 UDP RAW 编程、示例、API 源码、数据流

我们最为熟知的网络通信程序接口应该是 Socket。LwIP 自然也提供了 Socket 编程接口,不过,LwIP 的 Socket 编程接口都是使用最底层的接口来实现的。我们这里要学习的 UDP RAW 编程则是指的直接使用 LwIP 的最底层 UDP 接口来直接实现应用层功能。这里先来一张图,对 LwIP 内部…

电商技术揭秘营销相关系列文章合集(4)

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘相关系列文章合集&#xff08;3&#xff09; 文章目录 引言集合说明集合文章列表 引言 在数字化浪潮的推动下&#xff0c;电商行…

【35分钟掌握金融风控策略25】定额策略实战2

目录 基于收入和负债的定额策略 确定托底额度和盖帽额度 确定基础额度 基于客户风险评级确定风险系数 计算最终授信额度 确定授信有效期 基于收入和负债的定额策略 在实际生产中&#xff0c;客户的收入和负债数据大多无法直接获得&#xff0c;对于个人的收入和负债数据&…