刨析数据结构(二)

🌈个人主页:小田爱学编程
🔥 系列专栏:数据结构————"带你无脑刨析"
🏆🏆关注博主,随时获取更多关于数据结构的优质内容!🏆🏆


😀欢迎来到小田代码世界~
😁 喜欢的小伙伴记得一键三连哦 ૮(˶ᵔ ᵕ ᵔ˶)ა


一.线性表的链式储存

链表:线性表的链式储存方式,逻辑结构不一定连续,物理结构不一定连续

描述:由数据域和指针域组成

🌏头结点:点是为了操作方便而设立的,放在第一个元素结点之前,不保存任何有意义的数据

🌏头节点:即为指向第一个节点的地址 

🔥链表分类:八种

👨‍🚀 以单链表(不带头单向不循环链表)

 二.单链表

1.优缺点

🔥任意位置插入删除,时间复杂度小
🔥没有增容问题,插入一个开辟一个空间

🔥不支持随机访问

2.创建

//定义链表
typedef int SLTDataType;//数值域
//链表是由节点组成
typedef struct SListNode
{SLTDataType data;//int datastruct  SListNode* next;//它用来存储当前节点的下一个节点的地址
}SLTNode;//typedef struct SListNode SLTNode;

3.打印

void SLTPrint(SLTNode* phead) {SLTNode* pcur = phead;while (pcur){printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}
SLTNode* plist = node1;
SLTPrint(plist);

 

3.申请空间

SLTNode* SLTBuyNode(SLTDataType x) {SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL) {perror("malloc fail!");exit(1);}newnode->data = x;newnode->next = NULL;return newnode;
}

4.增加元素

尾插:

void SLTPushBack(SLTNode** pphead, SLTDataType x) {assert(pphead);SLTNode* newnode = SLTBuyNode(x);//链表为空,新节点作为pheadif (*pphead == NULL) {*pphead = newnode;return;}//链表不为空,找尾节点SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}//ptail就是尾节点ptail->next = newnode;
}

头插:

void SLTPushFront(SLTNode** pphead, SLTDataType x) {assert(pphead);SLTNode* newnode = SLTBuyNode(x);//newnode *ppheadnewnode->next = *pphead;*pphead = newnode;
}

在指定位置插入

//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x) {assert(pphead);assert(pos);//要加上链表不能为空assert(*pphead);SLTNode* newnode = SLTBuyNode(x);//pos刚好是头结点if (pos == *pphead) {//头插SLTPushFront(pphead, x);return;}//pos不是头结点的情况SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}//prev -> newnode -> posprev->next = newnode;newnode->next = pos;
}

5.删除元素

 尾删

void SLTPopBack(SLTNode** pphead) {assert(pphead);//链表不能为空assert(*pphead);//链表不为空//链表只有一个节点,有多个节点if ((*pphead)->next == NULL) {free(*pphead);*pphead = NULL;return;}SLTNode* ptail = *pphead;SLTNode* prev = NULL;while (ptail->next){prev = ptail;ptail = ptail->next;}prev->next = NULL;//销毁尾结点free(ptail);ptail = NULL;
}

 头删

void SLTPopFront(SLTNode** pphead) {assert(pphead);//链表不能为空assert(*pphead);//让第二个节点成为新的头//把旧的头结点释放掉SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}

🔥指定位置删除:注意删除的逻辑

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos) {assert(pphead);assert(*pphead);assert(pos);//pos刚好是头结点,没有前驱节点,执行头删if (*pphead == pos) {//头删SLTPopFront(pphead);return;}SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}//prev pos pos->nextprev->next = pos->next;free(pos);pos = NULL;
}
void SLTEraseAfter(SLTNode* pos) {assert(pos);//pos->next不能为空assert(pos->next);//pos  pos->next  pos->next->nextSLTNode* del = pos->next;pos->next = pos->next->next;free(del);del = NULL;
}

6.修改元素

//给一个数据,找到这个数据所在的节点,并用新数据修改
void SListChangeDate(SLTNode*pphead, SLTDataType x, SLTDataType y)
//不需要改变节点的地址,所以值传递即可 
//x是查找的数据,y是新的数据,用来修改查找的数据                                              
{SLTNode*cru = pphead;while (cru != NULL)//如果没有节点,根本不会进入循环去找{if (cru->data == x){cru->data = y;break;//修改完数据后,就跳出循环}else{cru = cru->next;}}if (cru == NULL)//如果循环完单链表,没有找到要修改的那个数据{printf("要修改的数据不存在,请重新修改数据\n");}else{printf("修改成功\n");}
}

7.查找元素

SLTNode* SLTFind(SLTNode** pphead, SLTDataType x) {assert(pphead);//遍历链表 SLTNode* pcur = *pphead;while (pcur) //pcur != NULL{if (pcur->data == x) {return pcur;}pcur = pcur->next;}//没有找到return NULL;
}

8.销毁链表

void SListDesTroy(SLTNode** pphead) {assert(pphead);assert(*pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}

三.双向链表

1.注意

🔥带头双向循环链表

🔥当链表中只要头节点的时候,为空链表

🔥头节点是不能删除的,指向可以改变

🔥不需要改变头节点的指向,不需要传二级指针

🔥二级指针对实参会产生影响 

 2.创建

typedef int LTDataType;
typedef struct ListNode {LTDataType data;struct ListNode* prev;struct ListNode* next;
}LTNode;

3.打印

LTNode* LTInit() {LTNode* phead = LTBuyNode(-1);return phead;
}

4.增加元素

尾插(不需要找尾操作

//尾插
void LTPushBack(LTNode* phead, LTDataType x) {assert(phead);LTNode* newnode = LTBuyNode(x);//phead phead->prev(ptail)  newnodenewnode->next = phead;newnode->prev = phead->prev;phead->prev->next = newnode;phead->prev = newnode;
}

 头插

//头插
void LTPushFront(LTNode* phead, LTDataType x) {assert(phead);LTNode* newnode = LTBuyNode(x);//phead newnode phead->nextnewnode->next = phead->next;newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;
}

任意位置插入

//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x) {assert(pos);LTNode* newnode = LTBuyNode(x);//pos newnode pos->nextnewnode->next = pos->next;newnode->prev = pos;pos->next->prev = newnode;pos->next = newnode;
}
//删除pos位置的数据
void LTErase(LTNode* pos) {assert(pos);//pos->prev pos  pos->nextpos->next->prev = pos->prev;pos->prev->next = pos->next;free(pos);pos = NULL;
}

5.删除元素

头删

void LTPopFront(LTNode* phead) {assert(phead);assert(phead->next != phead);LTNode* del = phead->next;LTNode* next = del->next;//phead del nextnext->prev = phead;phead->next = next;free(del);del = NULL;
}

 尾删

void LTPopBack(LTNode* phead) {assert(phead);//链表为空:只有一个哨兵位节点assert(phead->next != phead);LTNode* del = phead->prev;LTNode* prev = del->prev;prev->next = phead;phead->prev = prev;free(del);del = NULL;
}

 任意位置删除

void LTErase(LTNode* pos) {assert(pos);//pos->prev pos  pos->nextpos->next->prev = pos->prev;pos->prev->next = pos->next;free(pos);pos = NULL;
}

6.修改元素

void DeleteNode(LTNode** pHead, LTNode* toBeDeleted) {if (pHead == NULL || toBeDeleted == NULL) {return;}LTNode* head = *pHead;// 要删除的节点是头节点if (head == toBeDeleted) {*pHead = toBeDeleted->next;}// 调整前驱节点的next指针if (toBeDeleted->prev != NULL) {toBeDeleted->prev->next = toBeDeleted->next;}// 调整后继节点的prev指针if (toBeDeleted->next != NULL) {toBeDeleted->next->prev = toBeDeleted->prev;}free(toBeDeleted);
}

7.查找元素

LTNode* LTFind(LTNode* phead, LTDataType x) {assert(phead);LTNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x) {return pcur;}pcur = pcur->next;}return NULL;
}

8.销毁链表

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;
}

🥇这是博主年前的最后一篇文章哦,年后再继续更新,年后会开启新的刷题专栏!😊

🥇还有不到不到一周就过年喽!祝大家新的一年财源滚滚,学习进步,身体健康,咱们明年见! 

 🎁🎁🎁今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,您的支持就是我前进的动力!

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

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

相关文章

【音视频 ffmpeg 】直播推流QT框架搭建

简介: 【音视频 ffmpeg 】直播推流QT框架搭建 3个线程 一个做视频解码一个做音频解码一个做复用推流 视频解码线程展示 #include "videodecodethread.h" VideodecodeThread::VideodecodeThread(QObject *parent):QThread(parent) {avdevice_register_a…

【前端web入门第三天】01 css定义和引入方式 四种标签选择器

文章目录: 1.css 定义 2.css引入方式 3.选择器 3.1 标签选择器 3.2 类选择器 3.3 id选择器 3.4 通配符选择器 4. 画盒子 1.css 定义 层叠样式表(Cascading Style Sheets,缩写为CSS),是一种样式表语言,用来描述HTML文档的呈现(美…

一键部署幻兽帕鲁服务器免费一年方案

一、背景介绍 简单讲一下历程,幻兽帕鲁从在1月19日上线,24小时内在线人数峰值便突破200万,作为2024年第一款现象级游戏,《幻兽帕鲁》上线后,由于人数太多,频现服务器过载导致游戏卡顿掉线的情况。为了能够…

前端入门第三天

目录 一、CSS定义 二、CSS引入方式 三、基础选择器 1.标签选择器 2.类选择器 3.id选择器 4.通配符选择器 5.画盒子 四、文字控制属性 1.字体大小 2.字体粗细 3.字体倾斜 4.行高 1.行高-垂直居中 5.字体族 6.font复合属性 7.文本缩进 8.文本对齐方式 1.水平对…

C#,打印漂亮的贝尔三角形(Bell Triangle)的源程序

以贝尔数为基础,参考杨辉三角形,也可以生成贝尔三角形(Bell triangle),也称为艾特肯阵列(Aitkens Array),皮埃斯三角形(Peirce Triangle)。 贝尔三角形的构造…

Pycharm Community 配置调试Behave

前提:python小白,临时搞python项目,公司限制使用Pycharm版本,故只能使用社区版,然而官方有明确说明:只有Professional版支持Behave。故研究了半天才整清楚社区版调试Behave的设置 没有进行下面的步骤之前&…

Unity | 渡鸦避难所-9 | 角色名字及血条等信息

1 效果预览 游戏中角色的名字和血条是非常重要的元素,它们可以帮助玩家了解角色的身份和状态。在 Unity 中,可以使用 UGUI 来实现这些功能 2 实现方案 1 画布 (Canvas) 画布 (Canvas) 组件表示进行 UI 布局和渲染的抽象空间。所有 UI 元素都必须是附加…

Keil软件某些汉字输出乱码,0xFD问题,51单片机

1. 问题 keil软件输入某些汉字的时候会输出乱码,例如:升、 数 2. 原因 keil软件会忽略0xFD。 升的GB2312编码为 0xc9fd,keil解析为0xc9数的GB2312编码为 0xcafd,keil解析为0xca 关于Keil软件中0xFD问题的说明 3. 解决方案1 …

协作办公开源神器:ONLYOFFICE

目录 前言ONLYOFFICE为什么选择ONLYOFFICE强大的文档编辑功能多种协作方式多人在线协同支持跨端多平台连接器安全性极高本地部署 ONLYOFFICE 8.0版本震撼来袭可填写的 PDF 表单显示协作用户头像更新插件界面设计更快更强大 总结 前言 近几年来,随着互联网技术的不断…

gilab 展示测试用例结果详情页面

Python 此示例使用带有 --junitxmlreport.xml 标志的 pytest 将输出格式化为 JUnit 报告 XML 格式:gitlab 会自动去解析report.xml 这个文件,并且将每个case的测试结果展示在gitlab中pytest:stage: testscript:- pytest --junitxmlreport.xmlartifacts:w…

PyTorch的nn.Module类的详细介绍

在PyTorch中,nn.Module 类是构建神经网络模型的基础类,所有自定义的层、模块或整个神经网络架构都需要继承自这个类。nn.Module 类提供了一系列属性和方法用于管理网络的结构和训练过程中的计算。 1. PyTorch中nn.Module基类的定义 在PyTorch中&#xff…

U盘损坏电脑无法识别怎么修复?

USB闪存器简称为U盘,据谐音也称“优盘”,是一种可移动的存储设备,通过USB接口连接到电脑。因其便于携带且存储容量大,很多用户都使用U盘来存储文件资料、图片、视频等个人数据。但常使用U盘的用户,经常会遇到因U盘损坏…