双链表的实现(数据结构)

链表总体可以分为三大类

一、无头和有头

二、单向和双向

三、循环和不循环

   从上面分类得知可以组合成8种不同类型链表,其中单链表最为简单,双联表最为复杂,两种链表都实现后其余链表都不成问题。

  我们前期博客已将完成了单向无头不循环链表(单链表)的实现,本期博客我们实现双向有头循环链表的实现。

————————————————————————————

说明:

  因为此双链表有头结点,(头结点不存储任何有效数据,双链表中只有头结点时为空链表)

  因此我们无需修改头结点的地址,只需要改变头结点中前驱指针和后面指针的指向即可,所以传参时只需要传头结点的地址即可。

代码实现:

List.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int LTDataType;typedef struct ListNode
{struct ListNode* prev;struct ListNode* next;LTDataType data;
}LTNode;//void LTInit(LTNode** pphead);
LTNode* LTInit();
void LTDestroy(LTNode* phead);//为了保持接口一致性,需要在外部将phead置空。//保留头节点其他的删去
void LTClear(LTNode* phead);
LTNode* BuyNode(LTDataType x);void LTPrint(LTNode* phead);
bool LTEmpty(LTNode* phead);//判断是否为空void LTPushBack(LTNode* phead, LTDataType x);
void LTPopBack(LTNode* phead);void LTPushFront(LTNode* phead, LTDataType x);
void LTPopFront(LTNode* phead);
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x);
void LTErase(LTNode* pos);LTNode* LTFind(LTNode* phead, LTDataType x);

List.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"List.h"LTNode* LTInit()
{LTNode* phead = BuyNode(-1);return phead;
}LTNode* BuyNode(LTDataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL){perror("malloc fail!");exit(1);}newnode->prev = newnode->next = newnode;newnode->data = x;return newnode;
}void LTDestroy(LTNode* phead)
{//哨兵位不能为空assert(phead);LTNode* pcur = phead->next;while (pcur!=phead){LTNode* next = pcur->next;free(pcur);pcur = next;}free(phead);phead = NULL;
}
//清除链表的内容
void LTClear(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){LTNode* next = pcur->next;free(pcur);pcur = next;}phead->next = phead;phead->prev = phead;
}
void LTPrint(LTNode* phead)
{//链表不能为空assert(phead);LTNode* pcur = phead->next;while (pcur!=phead){printf("%d->",pcur->data);pcur = pcur->next;}printf("\n");
}
bool LTEmpty(LTNode* phead)
{if (phead->next = phead){return true;}else{return false;}
}void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = BuyNode(x);LTNode* ptail = phead->prev;ptail->next = newnode;newnode->prev = ptail;newnode->next = phead;phead->prev = newnode;
}
void LTPopBack(LTNode* phead)
{assert(phead);//链表不能为空assert(phead->next!=phead);LTNode* ptail = phead->prev;LTNode* prev = ptail->prev;phead->prev = prev;prev->next = phead;free(ptail);ptail = NULL;
}void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = BuyNode(x);LTNode* next = phead->next;phead->next = newnode;newnode->prev = phead;newnode->next = next;next->prev = newnode;}
void LTPopFront(LTNode* phead)
{assert(phead);assert(phead->next != phead);LTNode* pos = phead->next;LTNode* next = pos->next;phead->next = next;next->prev = phead;free(pos);pos = NULL;
}
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = BuyNode(x);LTNode* next = pos->next;//pos newnode nextpos->next = newnode;newnode->prev = pos;newnode->next = next;next->prev = newnode;
}
void LTErase(LTNode* pos)
{assert(pos);LTNode* prev = pos->prev;LTNode* next = pos->next;prev->next = next;next->prev = prev;free(pos);pos = NULL;
}
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;while (pcur->data!=x && pcur!=phead){pcur = pcur->next;}if (pcur->data == x){return pcur;}else{return NULL;};
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"List.h"int main()
{LTNode* phead = LTInit();if(LTEmpty(phead)){printf("链表为空\n");}LTPushBack(phead,1);LTPushBack(phead,2);LTPushBack(phead,3);LTPushBack(phead,4);LTPrint(phead);LTPopBack(phead);LTPopBack(phead);LTPrint(phead);LTPopFront(phead);LTPrint(phead);LTPushFront(phead,100);LTPushFront(phead,200);LTPushFront(phead,300);LTPrint(phead);LTNode* ret= LTFind(phead,200);if (ret){LTErase(ret);}else{printf("未找到,无法删除\n");}LTPrint(phead);LTNode* ret2 = LTFind(phead, 2);if (ret2){LTInsert(ret2, 3);}else{printf("未找到,无法插入\n");}LTPrint(phead);LTDestroy(phead);phead = NULL;return 0;
}

这个博客如果对你有帮助,给博主一个免费的点赞就是最大的帮助

欢迎各位点赞,收藏和关注哦

如果有疑问或有不同见解,欢迎在评论区留言哦

后续我会一直分享双一流211西北大学软件(C,数据结构,C++,Linux,MySQL)的学习干货以及重要代码的分享

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

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

相关文章

如何一键发布离线地图(二次开发)

离线地图发布工具支持 离线浏览 离线地图二次开发 离线工具应用(绘制&#xff1a;点、线、面&#xff0c;导入导出矢量数据)以及轨迹纪录等等应用&#xff0c;具体可参看&#xff1a;演示实例 Bigemap Server离线地图服务器下载地址&#xff1a;http://download.bigemap.com…

图机器学习(3)-面向节点的人工特征工程

0 问题引入 地铁导航图 计算机是看不懂这些图&#xff0c;计算机只能看懂向量、矩阵。 传统图机器学习只讨论连接特征。 构造一个新的特征 x 1 x 2 x_1x_2 x1​x2​&#xff0c;有利于分开这种数据。 人需要去翻译这些计算机不懂的特征&#xff0c;变成计算机可以懂…

二叉搜索树(BST)的创建及增,删,查,改(详解)

目录 初识二叉搜索树&#xff08;BST&#xff09;&#xff1a; 二叉搜索树查找元素&#xff1a; 二叉搜索树修改元素: 二叉搜索树中的增加元素&#xff1a; 二叉搜索树中的删除元素&#xff1a; 初识二叉搜索树&#xff08;BST&#xff09;&#xff1a; 一张图简要概括二…

RNN(Recurrent Neural Networks)循环神经网络

循环神经网络&#xff08;Recurrent Neural Network&#xff0c;简称RNN&#xff09;是一种处理序列数据的神经网络结构&#xff0c;它具有记忆能力&#xff0c;能够捕捉序列中的时序信息。RNN在自然语言处理、时间序列预测等方面有着很多的应用。 一、RNN 的基本结构 RNN的包…

常州大学-吴颖:参加数维杯竞赛后,我成功拿到梦寐以求的奖项

转眼间&#xff0c;数维杯数模竞赛已经进行到了第八年&#xff0c;这八年中&#xff0c;成千上万的数模人乘着属于自己的船成功抵达梦想的彼岸&#xff0c;每一场比赛都留下了他们努力的痕迹&#xff0c;更成为每次想起都觉得极为宝贵的经历。 当然&#xff0c;每个人的参赛经…

【算法 高级数据结构】树状数组:一种高效的数据结构(一)

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a;算法题、 基础算法~赶紧来学算法吧 &#x1f4a1;往期推荐&#xff1a; 【算法基础 & 数学】快速幂求逆元&#xff08;逆元、扩展欧几里得定理、小费马定理&#x…

现货商品购销挂牌交收系统VUE源码

现货商品购销挂牌交收系统的VUE源码涉及具体的技术实现和系统设计&#xff0c;这通常是一个复杂且专业性的任务&#xff0c;通常由开发团队根据具体业务需求和技术要求来完成。由于源码的复杂性和版权问题&#xff0c;我无法直接提供完整的现货商品购销挂牌交收系统的VUE源码。…

【C++杂货铺】详解string

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 为什么学习string &#x1f4c1; 认识string&#xff08;了解&#xff09; &#x1f4c1; string的常用接口 &#x1f4c2; 构造函数 &#x1f4c2; string类对象的容量操作 &#x1f4c2; string类对象的访问以及遍历操…

yolov8多batch推理,nms后处理

0. 背景 在高速公路监控视频场景下&#xff0c;图像分辨率大都是1920 * 1080或者2560 * 1440&#xff0c;远处的物体&#xff08;车辆和行人等&#xff09;都比较小。考虑需要对图像进行拆分&#xff0c;然后把拆分后的数据统一送入模型中&#xff0c;推理的结果然后再做nms&am…

看完不会来揍我 | 生存分析详解 | 从基础概念到生存曲线绘制 | 代码注释 + 结果解读

大名鼎鼎的生存分析来咯&#xff01;今天我就不叭叭叭了&#xff0c;咱们直接开始冲&#xff01;&#xff08;字有点多&#xff0c;希望大家不要嫌弃&#xff01;&#xff09; 提前说一句&#xff0c;我们今天介绍的K-M曲线主要用于比较不同组别生存曲线之间的差异&#xff0c;…

IOS开发0基础入门UIkit-1cocoapod安装、更新和使用 , 安装中出现的错误及解决方案 M1或者M2安装cocoapods

cocoapod是ios开发时常用的包管理工具 1.M1或者是M2系统安装cocoapods先操作一下两个设置 1、打开访达->应用->实用工具->终端->右键点击终端->显示简介->勾选使用 Rosetta 打开&#xff0c;关闭终端&#xff0c;重新打开。 2、打开访达->应用->Xcod…

【elasticsearch】ES的JAVA工具类完整版(待完成...)

springboot 的 elasticsearch 版本: 7.15.2 前情提要: 1.首先要理解 elasticsearch 对于【数据类型】很严格,如果字段类型不规范,在 检索/排序/聚合 时候类型不正确就会出现报错或者查不到数据的问题。所以在一般String类型插入结构如下: 这样的结构,不仅可以支持分词查…