【数据结构】双向链表(链表实现+测试+原码)

前言

在双向链表之前,如果需要查看单链表来复习一下,链接在这里:

http://t.csdnimg.cn/Ib5qS

1.双向链表


1.1 链表的分类

实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:

1.1.1 单向或者双向

1.1.2 带头或者不带头

1.1.3 循环或者非循环

虽然有这么多的链表的结构,但是我们实际中最常用还是两种结构:

1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。

2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,今天我们就来实现这种代码。

1.2 双向链表的实现

DList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "DList.h"LTNode* BuyLTNode(LTDataType x)
{LTNode* node = (LTNode*)malloc(sizeof(LTNode));if (node == NULL){perror("Malloc fail");exit(-1);}node->data = x;node->next = NULL;return node;
}
LTNode* LTInit()
{LTNode* phead  = BuyLTNode(-1);phead->next = phead;phead->prev = phead;return phead;
}void LTPrint(LTNode * phead)
{assert(phead);printf("phead<=>");LTNode* cur = phead->next;while (cur != phead){printf("%d<=>", cur->data);cur = cur->next;}printf("\n");
}void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);//LTNode* tail = phead->prev;//LTNode* newnode = BuyLTNode(x);//newnode->prev = tail;//tail->next = newnode;//newnode->next = phead;//phead->prev = newnode;LTInsert(phead->prev, x);}void LTPopBack(LTNode* phead)
{LTNode* del = NULL;//assert(phead);//if (phead->prev != phead)//链表指向自己,说明为空//{//	del = phead->prev;//	phead->prev = phead->prev->prev;//	phead->prev->next = phead;//}//else//	printf("链表为空,无需尾删");//free(del);LTErase(phead->prev);
}void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);//newnode->next = phead->next;	//先改变新插入的值,以免链表断开//newnode->prev = phead;//phead->next->prev = newnode;	//改变原本第二个节点的值//phead->next = newnode;			//改变为第一个节点//更稳妥的办法:双指针//LTNode* newnode = BuyLTNode(x);//LTNode* first = phead->next;//phead->next = newnode;//newnode->prev = phead;//newnode->next = first;//first->prev = newnode;LTInsert(phead->next, x);
}
//头删
void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead);//LTNode* first = phead->next;//LTNode* second = first->next;//free(first);//phead->next = second;//second->prev = phead;LTErase(phead->next);
}int LTSize(LTNode* phead)
{assert(phead);int size = 0;LTNode* cur = phead->next;while (cur != NULL){size++;cur = cur->next;}return size;
}void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* posPrev = pos->prev;LTNode* newnode = BuyLTNode(x);posPrev->next = newnode;newnode->prev = posPrev;newnode->next = pos;pos->prev = newnode;}
//删除pos位置
void LTErase(LTNode* pos)
{assert(pos);LTNode* posPrev = pos->prev;LTNode* posNext = pos->next;free(pos);posPrev->next = posNext;posNext->prev = posPrev;
}//寻找值
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);assert(phead->next);LTNode* pos = phead->next;while (pos){if (pos->data == x){return pos;}pos = pos->next;}
}//删除表
void LTDestroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}
}

DList.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int LTDataType;
typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}LTNode;
//申请空间
LTNode* BuyLTNode(LTDataType x);
//初始化指针
LTNode* LTInit();
//打印
void LTPrint(LTNode* phead);
//尾插
void LTPushBack(LTNode* phead, LTDataType x);
//尾删
void LTPopBack(LTNode* phead);
//头插
void LTPushFront(LTNode* phead, LTDataType x);
//头删
void LTPopFront(LTNode* phead);
//记录个数
int LTSize(LTNode* phead);
//pos之前插入
void LTInsert(LTNode* pos, LTDataType x);
//删除pos位置
void LTErase(LTNode* pos);
//寻找值
LTNode* LTFind(LTNode* phead, LTDataType x);
//删除表
void LTDestroy(LTNode* phead);

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "DList.h"void TestList1()
{LTNode* plist = NULL;plist = LTInit();LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPushBack(plist, 5);LTPrint(plist);LTPopBack(plist);LTPrint(plist);LTPushFront(plist, 99);LTPrint(plist);LTPopFront(plist);LTPrint(plist);LTNode* testlist = LTFind(plist, 5);LTPrint(testlist);}
int main()
{TestList1();}

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

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

相关文章

Redis集群模型

主从 全量同步 增量同步 哨兵 分片集群

选择影视行业创业的原因,影视从业者创业成功的秘密

一、教程描述 本套教程是面向影视从业者的创业教程&#xff0c;主讲人将把自己的创业经验、行业观察、成长心得分享给大家。如果你正在创业&#xff0c;这门课可以让你飞速成长、弯道超车。主讲人积累的行业经验&#xff0c;会让你比大多数同行站的更高&#xff0c;看的更宽。…

k8s-资源限制与监控 15

资源限制 上传实验所需镜像 Kubernetes采用request和limit两种限制类型来对资源进行分配。 request(资源需求)&#xff1a;即运行Pod的节点必须满足运行Pod的最基本需求才能 运行Pod。 limit(资源限额)&#xff1a;即运行Pod期间&#xff0c;可能内存使用量会增加&#xff0…

七、热身仪式(Warm-Up Rituals)

5.Warm Up Rituals 五、热身仪式 A warm up ritual is your per flight checklist you go through before you start focusing for a big session.It may be checking that you have water, that you don’t need to use the bathroom, that your phone is turned off or you’…

嵌入式硬件越老越吃香,确实没错!

不知不觉已经从事硬件设计7年多了&#xff0c;7年对于一个从事硬件设计来说能有几个完整的生涯。2016年毕业&#xff0c;2023年即将结束&#xff0c;我已经在汽车这行业“摸爬滚打”了7年的时光。 回顾这7年&#xff0c;自己真的成长了很多很多。有项目失败整改的经验收获&…

k8s-深入理解Service(为Pod提供负载均衡和发现)

一、Service存在的意义 二、Service的定义和创建 Pod与Service的关系 Service的定义和创建 三、Service使用NodePort对外暴露应用 四种类型&#xff0c;常用的三种&#xff1a; 指定Service的NodePort端口 在实际生产中&#xff0c;k8s的集群不会直接暴露在公网中&#xff0c…

Linux开发工具的使用 (gcc/g++ | gdb)

目录 一、gcc/g 1.关于gcc/g 2.gcc如何使用 gcc选项&#xff1a; 预处理&#xff1a; 编译: 汇编: 连接: 函数库是什么&#xff1a; 函数库分为动态库和静态库两种 二、调试器gdb 1.关于gdb 2. gdb的使用 gdb选项&#xff1a; Linux是一个广泛用于开发的操作系统&…

KAJIMA CORPORATION CONTEST 2024(AtCoder Beginner Contest 340)ABCDEF 视频讲解

这场比较郁闷&#xff0c;C题短路&#xff0c;连续4次WA&#xff0c;导致罚时太多 A - Arithmetic Progression Problem Statement Print an arithmetic sequence with first term A A A, last term B B B, and common difference D D D. You are only given inputs for w…

43.1k star, 免费开源的 markdown 编辑器

简介 项目名&#xff1a; MarkText-- 简单而优雅的开源 Markdown 编辑器 Github 开源地址&#xff1a; https://github.com/marktext/marktext 官网&#xff1a; https://www.marktext.cc/ 支持平台&#xff1a; Linux, macOS 以及 Windows。 操作界面&#xff1a; 在操作界…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Blank组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Blank组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Blank组件 空白填充组件&#xff0c;在容器主轴方向上&#xff0c;空白填充组件具…

linux优化空间完全卸载mysql——centos7.9

文章目录 ⭐前言⭐linux命令使用&#x1f496; 基础命令&#x1f496; 内存优化&#x1f496; 完全删除mysql ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;linux优化空间&完全卸载mysql——centos7.9。 linux内存分配 在Linux中&#xff0c;内存分配是通过几种…

Caché 为什么在医疗系统中吐槽

目前所知的 Cach 是应用在医院信息系统&#xff08;即 HIS&#xff09;&#xff0c;据说在欧美医疗卫生行业&#xff0c;Cach 占了 70% 的市场份额。国内的东华软件就是采用 Cach 数据库&#xff0c;东华软件在国内医院市场占有率大致为 20%&#xff0c;其中包括北京协和医院、…