双链表定义与操作

news/2024/9/21 17:05:09/文章来源:https://www.cnblogs.com/asherof/p/18424228

双链表的定义

 与单链表不同的地方在于指针,双链表的指针多了个前向指针。

点击查看代码
typedef struct DNode{ElemType data;DNode *prior, *next;
}*DLinkList, DNode;

双链表的初始化(initial)

 双链表的创建也可分为带头节点和不带头节点(这里只放了不带头的初始化)。

点击查看代码
// 带头节点创建 
bool InitDHList(DLinkList &L){L = (DNode *)malloc(sizeof(DNode));if(L == NULL) return 0;L->next = NULL;L->prior = NULL;return 1;
}

双链表的插入(Insert)

 双链表的插入方式都和后插方式大致相同(这里提供了前插和后插)。

点击查看代码
// 双链表的插入(在p节点后插入s节点)
bool InsertNextDNode(DNode *p, int x){DNode *s = (DNode *)malloc(sizeof(DNode));s->data = x;if(p == NULL || s == NULL) return 0;
//	s->next = p->next; (后插) 
//	if(p->next != NULL) // 如果p后面没有后继节点 
//		p->next->prior = s;
//	s->prior = p;
//	p->next = s;s->prior = p->prior; // (前插) if(p->prior != NULL) p->prior->next = s; // 如果p前面没有前继节点 s->next = p;p->prior = s;return 1; 
}

双链表的删除节点(Delete)

 双链表的删除操作。

点击查看代码
// 删除p节点的后继节点,将next改为prior,prior改为next就是删除p节点的前继节点 
bool DeleteNextNode(DNode *p){if(p == NULL) return 0;DNode *q = p->next;if(q == NULL) return 0;p->next = q->next;if(q->next != NULL) q->next->prior = p;free(q);return 1;
}

销毁链表(destroy)

点击查看代码
// 销毁链表
void DestoryList(DLinkList L){while(L->next != NULL){DeleteNextNode(L);}free(L);L = NULL;
} 

后项遍历:

void BackwardList(DNode *p){
while(p->next != NULL){
p = p->next;
cout << p->data << endl;
}
}

前项遍历:

void ForwardList(DNode *p){
while(p->prior != NULL){
p = p->prior;
cout << p->data << endl;
}
}

完整代码:

 注意:前向遍历只能使用前插操作才能遍历到值,后向遍历同理。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef int ElemType;
typedef struct DNode{ElemType data;DNode *prior, *next;
}*DLinkList, DNode;// 带头节点创建 
bool InitDHList(DLinkList &L){L = (DNode *)malloc(sizeof(DNode));if(L == NULL) return 0;L->next = NULL;L->prior = NULL;return 1;
}// 判断双链表是否为空(带头节点) 
bool Empty(DLinkList L){if(L->next == NULL) return 1;else return 0;
}// 双链表的插入(在p节点后插入s节点)
bool InsertNextDNode(DNode *p, int x){DNode *s = (DNode *)malloc(sizeof(DNode));s->data = x;if(p == NULL || s == NULL) return 0;
//	s->next = p->next; (后插) 
//	if(p->next != NULL) // 如果p后面没有后继节点 
//		p->next->prior = s;
//	s->prior = p;
//	p->next = s;s->prior = p->prior; // (前插) if(p->prior != NULL) p->prior->next = s; // 如果p前面没有前继节点 s->next = p;p->prior = s;return 1; 
}// 位序插入
bool InsertValPos(DLinkList L, int pos, int val){DNode *p = L;if(p == NULL) return 0;int j = 0;while(p != NULL && j < pos - 1){p = p->next;j ++;}if(p == NULL) return 0;DNode *s = (DNode *)malloc(sizeof(DNode));s->data = val;s->next = p->next;p->next->prior = s;s->prior = p;p->next = s;return 1;
} 
// 删除p节点的后继节点,将next改为prior,prior改为next就是删除p节点的前继节点 
bool DeleteNextNode(DNode *p){if(p == NULL) return 0;DNode *q = p->next;if(q == NULL) return 0;p->next = q->next;if(q->next != NULL) q->next->prior = p;free(q);return 1;
}
// 销毁链表
void DestoryList(DLinkList L){while(L->next != NULL){DeleteNextNode(L);}free(L);L = NULL;
} 
// 后向遍历 
void  BackwardList(DNode *p){while(p->next != NULL){p = p->next;cout << p->data << endl;}
}
// 前向遍历 
void  ForwardList(DNode *p){while(p->prior != NULL){p = p->prior;cout << p->data << endl;}
}
int main(){DLinkList L;InitDHList(L);int n; cin >> n;for(int i = 1;i <= n;i ++){int x; cin >> x;InsertNextDNode(L, x);}ForwardList(L);}

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

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

相关文章

了解如何在 lt;lines (Modulojs) 中创建 API 支持的 Zelda BOTW 怪物画廊 Web 组件

模数教程回来了!大家好!暑假结束后,我带着 modulo 教程回来了。我正在制作更多教程 - 请继续关注。也就是说,如果您对我的下一个主题有任何特别的想法,请务必在评论中告诉我!我的上一篇教程是关于 api 驱动的 pokmon dance party 组件的超级快速且有趣的“仅 html,无 js…

Cortex-A7 MPCore 架构

Cortex-A7 MPCore 架构 1)Cortex-A7 MPCore 简介 Cortex-A7 MPcore 处理器支持 1~4 核,通常是和 Cortex-A15 组成 big.LITTLE 架构的,Cortex-A15 作为大核负责高性能运算,比如玩游戏啥的, Cortex-A7 负责普通应用,因为 CortexA7 省电。 Cortex-A7 本身性能也不弱,不要…

Zlmedia搭建简记

进入新公司之后,发现他们的视频播放使用的是ZlmediaKit这个工具,自己尝试使用了一下发现很好用,于是在自己机器上搭建了一个服务玩玩。 因为没有在线的摄像头,所以这里采用的是ffmpeg推送mp4文件作为视频流输入,推送到zlmedia服务,再利用zlmedia本身所带的拉流服务,最终…

C 风格字符串函数

▲《C++ Primer》 P109 我们无法保证 c_str 函数返回的数组一直有效,事实上,如果后续的操作改变了 string 的值就可能让之前返回的数组失去效用。 WARNING: 如果执行完 c_str() 函数后程序想一直都能使用其返回的数组,最好将该数组重新拷贝一份。

基于IDF的ESP32S3-LVGL DEMO移植

简介 ESP32-32出色的性价比,较好的性能与内存空间,可以好利用来完成GUI显示库的加载 LVGL LVGL是一款比较流行的致力于MCU与MPU创建漂亮UI的嵌入式图形库,免费且开源。 硬件 硬件采用的是正点原子的ESP32-S3 屏幕使用的是SPI通信方式,配合IO口控制(RST,A0),来实现LCD屏幕…

nginx: 按ip地址限流

一,以固定的速度提供服务 语法: 例子 limit_req_zone $binary_remote_addr zone=test:10m rate=2r/s;server { location / { limit_req zone=test; }} 语法: imit_req_zone 用于设置限流和共享内存区域的参数,格式为: limit_req_zone key zone rate。 key: 定…

Free5GC源码研究(2) - 单个NF的软件架构

前文我们总览了free5gc的总体软件架构。整一个free5gc系统又由几个NF(Network Function)组成,所以本文继续深入研究单个NF的软件架构。要研究NF的软件架构,最直接的方式是找一个简单的NF来回观摩。free5gc/ausf算是比较简单的一个,然而我发现了一个更简单的NF,叫做andy89…

一,初始 MyBatis-Plus

一,初始 MyBatis-Plus @目录一,初始 MyBatis-Plus1. MyBatis-Plus 的概述2. 入门配置第一个 MyBatis-Plus 案例3. 补充说明:3.1 通用 Mapper 接口介绍3.1.1 Mapper 接口的 “增删改查”3.1.1.1 查询所有记录3.1.1.2 插入一条数据3.1.1.3 删除一条数据3.1.1.4 更新一条数据3.…

[神经网络与深度学习笔记]LDA降维

LDA降维 LinearDiscriminant Analysis 线性判别分析,是一种有监督的线性降维算法。与PCA保持数据信息不同,LDA的目标是将原始数据投影到低维空间,尽量使同一类的数据聚集,不同类的数据尽可能分散 步骤:计算类内散度矩阵\(S_b\) 计算类间散度矩阵\(S_w\) 计算矩阵\(S_w^{-1…

C++ 指针和迭代器支持的操作

▲ 《C++ Primer》 P96 指针也都支持上面的操作。

代码整洁之道--读书笔记(14)

代码整洁之道简介: 本书是编程大师“Bob 大叔”40余年编程生涯的心得体会的总结,讲解要成为真正专业的程序员需要具备什么样的态度,需要遵循什么样的原则,需要采取什么样的行动。作者以自己以及身边的同事走过的弯路、犯过的错误为例,意在为后来者引路,助其职业生涯迈上更…

hexo安装后报错hexo 不是内部或外部命令,也不是可运行的程序 或批处理文件。

hexo问题 之前利用hexo和gitee搭建了一个博客,但是最近gitee的gitpage停止服务了,便想着在github上搭建一个。 在到安装hexo这一步的时候,一直报错hexo 不是内部或外部命令,也不是可运行的程序 或批处理文件。 我的所有安装步骤和环境变量发现都没有错,反复配置后去找了一…