【数据结构】05.双向链表

一、双向链表的结构

在这里插入图片描述

注意:这里的“带头”跟前面我们说的“头节点”是两个概念,带头链表里的头节点,实际为“哨兵位”,哨兵位节点不存储任何有效元素,只是站在这里“放哨的”。
“哨兵位”存在的意义:遍历循环链表避免死循环。

二、双向链表的实现

2.1 双向链表结点的创建

typedef int DLType;
//创建结构体
typedef struct DList
{DLType data;struct DList* prev;struct DList* next;
}DL;

2.2 双向链表的初始化与销毁

//初始化phead
DL* init(void)
{DL* phead = BuyNewNode(0);return phead;
}
//销毁链表,这里需要主要phead是形参,这里的最后将phead置空并不能将原链表中的phead置空,
//因此原链表中的phead需要手动置空,详细实现见源码
void DLDesdroy(DL* phead)
{assert(phead);DL* tail =phead->next;while (tail != phead){DL* next = tail->next;free(tail); tail= next;}free(phead);phead = NULL;
}

2.3 双向链表的增删查改

由于多次创建结点,因此我们将它提炼为一个函数

//创造新的节点
DL* BuyNewNode(DLType  x)
{DL* newnode = (DL*)malloc(sizeof(DL));if (newnode == NULL){perror("malloc is failed!\n");return 1;}newnode->data = x;newnode->next = newnode->prev = newnode;return newnode;
}
//尾插
void  DLPushBack(DL* phead,DLType x)
{assert(phead);DL* newnode = BuyNewNode(x);newnode->next = phead;phead->prev->next = newnode;newnode->prev = phead->prev;phead->prev = newnode;
}//尾删
void DLPopBack(DL* phead)
{assert(phead);assert(phead->next != phead);DL* tail = phead->prev;DL* prev = tail->prev;prev->next = phead;phead->prev = prev;free(tail);tail = NULL;  }//头插
void DLPushFront(DL* phead, DLType x)
{assert(phead);DL* newnode = BuyNewNode(x);DL* first = phead->next;newnode->next = first;first->prev = newnode;phead->next = newnode;newnode->prev=phead;
}//头删
void DLPopFront(DL* phead)
{assert(phead);assert(phead->next != phead);DL* first = phead->next;DL* second = first->next;phead->next = second;second->prev = phead;free(first);first = NULL;
}//查找
DL* DLFind(DL* phead,DLType x)
{assert(phead);DL* cur = phead->next;while ( cur != phead){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}//pos位置插入数据
void DLInsert(DL* pos,DLType x)
{assert(pos);DL* newnode = BuyNewNode(x);DL* prev = pos->prev;prev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}//pos位置之后插入数据
void DLInsertAfter(DL* pos, DLType x)
{assert(pos);DL* newnode = BuyNewNode(x);DL* next = pos->next;newnode->next = next;next->prev = newnode;pos->next = newnode;newnode->prev = pos;
}//删除pos位置元素
void  DLErase(DL* pos)
{assert(pos);DL* next = pos->next;DL* prev = pos->prev;prev->next = next;next->prev = prev;free(pos);pos = NULL;
}

2.4 双向链表的打印

//打印链表
void DLPrint(DL* phead)
{DL* pcur = phead->next;while (pcur != phead){printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}

2.5 双向链表的源码

//DL.h#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int DLType;typedef struct DList
{DLType data;struct DList* prev;struct DList* next;
}DL;//初始化
DL* init(void);
//打印
void DLPrint(DL* phead);//尾插、尾删
void  DLPushBack(DL* phead, DLType x);
void DLPopBack(DL* phead);//头插、头删
void  DLPushFront(DL* phead, DLType x);
void  DLPopFront(DL* phead);//查找
DL* DLFind(DL* phead, DLType x);//指定位置插入数据、指定位置之后插入数据
void  DLInsert(DL* pos, DLType x);
void DLInsertAfter(DL* pos, DLType x);//删除pos
void  DLErase(DL* phead);void DLDesdroy(DL** phead);
//DL.c
#include "DList.h"//创造新的节点
DL* BuyNewNode(DLType  x)
{DL* newnode = (DL*)malloc(sizeof(DL));if (newnode == NULL){perror("malloc is failed!\n");return 1;}newnode->data = x;newnode->next = newnode->prev = newnode;return newnode;
}//初始化phead
DL* init(void)
{DL* phead = BuyNewNode(0);return phead;
}//打印链表
void DLPrint(DL* phead)
{DL* pcur = phead->next;while (pcur != phead){printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}//尾插
void  DLPushBack(DL* phead,DLType x)
{assert(phead);DL* newnode = BuyNewNode(x);newnode->next = phead;phead->prev->next = newnode;newnode->prev = phead->prev;phead->prev = newnode;
}//尾删
void DLPopBack(DL* phead)
{assert(phead);assert(phead->next != phead);DL* tail = phead->prev;DL* prev = tail->prev;prev->next = phead;phead->prev = prev;free(tail);tail = NULL;  }//头插
void DLPushFront(DL* phead, DLType x)
{assert(phead);DL* newnode = BuyNewNode(x);DL* first = phead->next;newnode->next = first;first->prev = newnode;phead->next = newnode;newnode->prev=phead;
}//头删
void DLPopFront(DL* phead)
{assert(phead);assert(phead->next != phead);DL* first = phead->next;DL* second = first->next;phead->next = second;second->prev = phead;free(first);first = NULL;
}//查找
DL* DLFind(DL* phead,DLType x)
{assert(phead);DL* cur = phead->next;while ( cur != phead){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}//pos位置插入数据
void DLInsert(DL* pos,DLType x)
{assert(pos);DL* newnode = BuyNewNode(x);DL* prev = pos->prev;prev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}//pos位置之后插入数据
void DLInsertAfter(DL* pos, DLType x)
{assert(pos);DL* newnode = BuyNewNode(x);DL* next = pos->next;newnode->next = next;next->prev = newnode;pos->next = newnode;newnode->prev = pos;
}//删除
void  DLErase(DL* pos)
{assert(pos);DL* next = pos->next;DL* prev = pos->prev;prev->next = next;next->prev = prev;free(pos);pos = NULL;
}//销毁链表
void DLDesdroy(DL* phead)
{assert(phead);DL* tail =phead->next;while (tail != phead){DL* next = tail->next;free(tail); tail= next;}free(phead);phead = NULL;
}

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

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

相关文章

人工智能系列-Pandas基础

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” Pandas简介 Pandas是Python语言的拓展程序库&#xff0c;用于数据分析。 Pandas是一个开放源码&#xff0c;BSD许可的库&#xff0c;提供高性能&#xff0c;易于使用的数据结…

YOLO V7网络实现细节(2)—网络整体架构总结

YOLO V7网络整体架构总结 YOLO v7网络架构的整体介绍 不同GPU和对应模型&#xff1a; ​​​​​​​边缘GPU&#xff1a;YOLOv7-tiny普通GPU&#xff1a;YOLOv7​​​​​​​云GPU的基本模型&#xff1a; YOLOv7-W6 激活函数&#xff1a; YOLOv7 tiny&#xff1a; leaky R…

vue项目实现堆叠卡片拖动切换效果

实际效果 实现流程 1. 实现卡片位置堆叠 将父元素的 position 设置成relative &#xff0c;卡片的position 设置成 absolute 即可。 2. 消除图片的移动 如果卡片上有图片&#xff0c;默认拖动的时候就会导致像上图一样变成了选中图片移动&#xff0c;从而没法触发拖动事件。消…

苹果电脑能玩赛博朋克2077吗 如何在mac上运行赛博朋克2077 crossover能玩什么游戏

各位喜欢赛博朋克风的一定不能错过《赛博朋克2077》。那么《赛博朋克2077》是一款什么样的游戏&#xff1f;《赛博朋克2077》在苹果电脑上可以运行吗&#xff1f;一起来看看介绍吧。 一、《赛博朋克2077》是一款什么样的游戏&#xff1f; 《赛博朋克2077》是一款由CD Projekt …

MIT6.s081 2021 Lab Traps

使用gdb调试xv6内核 从最近两个 Lab 开始&#xff0c;代码逻辑的复杂度明显上升&#xff0c;对内核进行调试可能是帮助理解操作系统机制的绝佳方法。因此在开始本 Lab 之前&#xff0c;我们先来配置一下针对 xv6 内核的 gdb 调试器。 安装 gdb-multiarch. 利用包管理工具进行…

基于Maximin的异常检测方法(MATLAB)

异常存在于各个应用领域之中&#xff0c;往往比正常所携带的信息更多也更为重要。例如医疗系统中疾病模式&#xff0c;信用卡消费中的欺诈行为&#xff0c;数据库中数据泄露&#xff0c;大型机器故障&#xff0c;网络入侵行为等。大数据技术体系的快速兴起与发展&#xff0c;加…

【React Native优质开源项目】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

字符串——string类的常用接口

一、string类对象的常见构造 二、string类对象的容量操作 三、string类对象的访问及遍历操作 四、string类对象的修改操作 一、string类对象的常见构造 1.string() ——构造空的string类对象&#xff0c;也就是空字符串 2.string(const char* s) ——用字符串来初始化stri…

【Linux】压缩命令——gzip,bzip2,xz

1.压缩文件的用途与技术 你是否有过文件太大&#xff0c;导致无法以正常的E-mail方式发送&#xff1f;又或学校、厂商要求使用CD或DVD来做数据归档之用&#xff0c;但是你的单一文件却都比这些传统的一次性存储媒介还要大&#xff0c;那怎么分成多块来刻录&#xff1f;还有&am…

【QT】显示类控件

显示类控件 显示类控件1. label - 标签2. LCD Number - 显示数字的控件3. ProgressBar - 进度条4. Calendar Widget - 日历5. Line Edit - 输入框6. Text Edit - 多行输入框7. Combo Box - 下拉框8. Spin Box - 微调框9. Date Edit & Time Edit - 日期微调框10. Dial - 旋钮…

Hive 高可用分布式部署详细步骤

目录 系统版本说明 hive安装包下载及解压 上传mysql-connector-java的jar包 配置环境变量 进入conf配置文件中&#xff0c;将文件重命名 在hadoop集群上创建文件夹 创建本地目录 修改hive-site.xml文件 同步到其他的节点服务器 修改node02中的配置 hive-site.xml 修改…

昇思25天学习打卡营第3天|MindSpore张量

# 打卡 目录 # 打卡 类 涉及知识点 1. 创建张量的4种方式 运行例子 2. 张量属性和索引 运行例子 3. 张量运算 运行例子 4. Tensor 与 Numpy 转换 5. 稀疏张量&#xff1a;CSR和COO CSRTensor 运行例子 COOTensor 运行例子 RowTensor 类 import mindspore from…

Linux系统的介绍和常用命令

文章目录 介绍常用命令文件和目录操作文件内容操作系统管理命令网络命令 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;Liunx系统 ✨文章内容&#xff1a;Liunx系统介绍 &…

2024年【危险化学品生产单位安全生产管理人员】考试总结及危险化学品生产单位安全生产管理人员考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品生产单位安全生产管理人员考试总结是安全生产模拟考试一点通总题库中生成的一套危险化学品生产单位安全生产管理人员考试试题&#xff0c;安全生产模拟考试一点通上危险化学品生产单位安全生产管理人员作业…

【xinference】(15):在compshare上,使用docker-compose运行xinference和chatgpt-web项目,配置成功!!!

视频演示 【xinference】&#xff08;15&#xff09;&#xff1a;在compshare上&#xff0c;使用docker-compose运行xinference和chatgpt-web项目&#xff0c;配置成功&#xff01;&#xff01;&#xff01; 1&#xff0c;安装docker方法&#xff1a; #!/bin/shdistribution$(…

路径跟踪算法之PID、PP、Stanley详细理解

一、前言 今天又来补作业了&#xff01; 在跟踪控制领域&#xff0c;PID&#xff08;Proportional-Integral-Derivative, 分别为比例、积分、微分&#xff09;、PP&#xff08; Pure-Puresuit, 纯跟踪&#xff09;、Stanley&#xff08;前轮反馈控制&#xff09;是三种最为常见…

STL——map和set

目录 一、set 二、map 1.插入 2.隆重介绍 [] A使用场景 B原理 一、set set即STL库中提供的K模型的二叉搜索树&#xff0c;他的函数使用和其他容器很相似&#xff0c;可以自行阅读文档#include <set> 本文旨对库中难以理解的函数作说明 二、map map即KV模型的二…

【全面讲解如何安装Jupyter Notebook!】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

1.2 如何让机器说人话?万字长文回顾自然语言处理(NLP)的前世今生 —— 《带你自学大语言模型》系列

本系列目录 《带你自学大语言模型》系列部分目录及计划&#xff0c;完整版目录见&#xff1a;带你自学大语言模型系列 —— 前言 第一部分 走进大语言模型&#xff08;科普向&#xff09; 第一章 走进大语言模型 1.1 从图灵机到GPT&#xff0c;人工智能经历了什么&#xff1…

针对tcp不出网打——HTTP隧道代理(以CFS演示)

目录 上传工具到攻击机 使用说明 生成后门文件 由于电脑短路无法拖动文件&#xff0c;我就wget发送到目标主机tunnel.php文件​ 成功上传​ 可以访问上传的文件 启动代理监听 成功带出 后台私信获取弹药库工具reGeorg 上传工具到攻击机 使用说明 生成后门文件 pyt…