当前位置: 首页 > news >正文

【数据结构】双向链表实现

 

  Yan-英杰的主页

悟已往之不谏 知来者之可追

    C++程序员,2024届电子信息研究生


 目录

一、什么是双向链表

二、双向链表的实现


一、什么是双向链表

 

        双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表

二、双向链表的实现

        List.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int LTDataType;typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;}LTNode;LTNode* LTInit();
void LTDestory(LTNode* phead);
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);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* BuyListNode(LTDataType x)
{LTNode* node = (LTNode*)malloc(sizeof(LTNode));if (node == NULL){perror("fail:malloc");exit(-1);}node->next = NULL;node->prev = NULL;node->data = x;return node;
}LTNode* LTInit()
{LTNode* phead = BuyListNode(-1);phead->next = phead;phead->prev = phead;return phead;
}
bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;
}void LTDestroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}free(phead);phead = NULL;
}
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);LTInsert(phead,x);
}void LTPopBack(LTNode* phead)
{assert(phead);assert(!LTEmpty(phead));LTErase(phead->prev);
}void LTPushFront(LTNode* phead,LTDataType x)
{assert(phead);LTInsert(phead->next,x);
}void LTPopFront(LTNode* phead)
{assert(phead);assert(!LTEmpty(phead));LTErase(phead->next);
}LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}//在Pos前一个位置添加节点
void LTInsert(LTNode* pos,LTDataType x)
{assert(pos);LTNode* prev = pos->prev;LTNode* newnode = BuyListNode(x);prev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}void LTErase(LTNode* pos)
{assert(pos);LTNode* p = pos->prev;LTNode* n = pos->next;p->next = n;n->prev = p;free(pos);pos = NULL;
}

   思路:

        BuyListNode函数

        BuyListNode的实现,我们在实现头插尾插时,为了更加遍历的实现功能,我们创建了BuyListNode函数,malloc一块新的空间,并且对其进行初始化,返回其类型

LTNode* BuyListNode(LTDataType x)
{LTNode* node = (LTNode*)malloc(sizeof(LTNode));if (node == NULL){perror("fail:malloc");exit(-1);}node->next = NULL;node->prev = NULL;node->data = x;return node;
}

       LTInit函数

        在实现该链表前,我们对其进行初始化,对其哨兵位的头节点,进行循环指向

        哨兵位头节点的出现,使得链表添加与删除效率大大提高

LTNode* LTInit()
{LTNode* phead = BuyListNode(-1);phead->next = phead;phead->prev = phead;return phead;
}

        LTInsert和LTErase函数

                LTInsert函数的实现:

                                                我们找到pos的前一个节点位置,进行操作,首先我们找到pos的前一个位置,保存该节点,创建新的节点,将pos前一个位置的节点next指向新节点,新节点的prev指向pos前一个位置,新节点的next指向pos,pos的前一个位置指向新节点

               LTErase函数的实现:

                                                删除pos位置的节点,先暴力检查是否为空,其中只有哨兵位的头节点,如果只有头节点则直接报错,保存pos位置节点的前一个节点和后一个节点,让pos的prev和next分别指向前一个位置和后一个位置的节点

void LTInsert(LTNode* pos,LTDataType x)
{assert(pos);LTNode* prev = pos->prev;LTNode* newnode = BuyListNode(x);prev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}void LTErase(LTNode* pos)
{assert(pos);LTNode* p = pos->prev;LTNode* n = pos->next;p->next = n;n->prev = p;free(pos);pos = NULL;
}

        LTPushBack与LTPopBack函数

                尾插与尾删功能,我们先对其进行暴力检查,通过LTInsert和LTErase函数进行实现该功能

void LTPushBack(LTNode* phead,LTDataType x)
{	assert(phead);LTInsert(phead,x);
}void LTPopBack(LTNode* phead)
{assert(phead);assert(!LTEmpty(phead));LTErase(phead->prev);
}

        LTPushFront和LTPopFront函数

         头插与头删功能,我们先对其进行暴力检查,通过LTInsert和LTErase函数进行实现该功能


void LTPushFront(LTNode* phead,LTDataType x)
{assert(phead);LTInsert(phead->next,x);
}void LTPopFront(LTNode* phead)
{assert(phead);assert(!LTEmpty(phead));LTErase(phead->next);
}

          LTDestory和LTPrint函数的实现

               LTPrint: 当我们功能实现时,LTPrint函数可在控制台进行打印和输出,优先找到哨兵位头节点的下一位,我们对其进行循环,当循环节点等于哨兵位时,停止循环

                LTDestory:当我们退出链表时,对其进行销毁

void LTDestroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}free(phead);phead = NULL;
}
void LTPrint(LTNode* phead)
{assert(phead);printf("<=phead=>");LTNode* cur = phead->next;while (cur != phead){printf("%d<=>",cur->data);cur = cur->next;}printf("\n");
}

                  ListTest.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "List.h"
void ListTest()
{LTNode* phead = LTInit();LTPushBack(phead, 1);LTPushBack(phead, 2);LTPushBack(phead, 3);LTPrint(phead);LTPopBack(phead);LTPrint(phead);LTPushFront(phead,10);LTPrint(phead);LTPopFront(phead);LTPrint(phead);
}int main()
{ListTest();return 0;
}

相关文章:

【数据结构】双向链表实现

Yan-英杰的主页 悟已往之不谏 知来者之可追 C程序员&#xff0c;2024届电子信息研究生 目录 一、什么是双向链表 二、双向链表的实现 一、什么是双向链表 双向链表也叫双链表&#xff0c;是链表的一种&#xff0c;它的每个数据节点中都有两个指针&#xff0c;分别指向直接后…...

无公网IP,SSH远程连接Linux CentOS服务器【内网穿透】

文章目录1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程本次教程我们来实现如何在外公网环境下&#xff0c;SSH远程连接家里/公司的Linux CentOS服务器&#xff0c;无需公网IP&#xff0c;也不需要设置路由器。 …...

CentOS 7+Docker搭建rabbitMQ无法访问15672端口

CentOS 7Docker搭建rabbitMQ无法访问15672端口 1.我拉取的镜像自带管理UI界面 所以不可能是没有开启管理UI界面的原因 2.防火墙关闭状态 所以也不是防火墙的问题 3.在虚拟机本机localhost:15672也访问不了 4.端口监听是正常的 5.最后发现我容器内curl能够通&#xff0c;容…...

面试官:如何保证接口幂等性?一口气说了9种方法!

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址 大家好&#xff0c;我是大彬~ 今…...

蓝桥杯刷题冲刺 | 倒计时14天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.最长递增2.走迷宫3.解立方根4.回文特判5.修改数组1.最长递增 题目 链接&#xff1a; 最长递增…...

【数据结构】树的概念

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...

Qt Glog toStdWString转char* 中文乱码

#include <QTextCodec>void LogWriter::init(void) {InitGoogleLogging("ui-fundus");char log_path[256] {0};FLAGS_stderrthreshold GLOG_INFO; // INFO WARNING ERROR FATAL, 是输出到stderr(app Output/cli)的阀值FLAGS_alsologtostderr false; // 当这…...

基于线性Kalman观测器(LKF)的2、4、7自由度悬架主动控制合集

目录 前言 1. 1/4车悬架仿真分析 2. 1/2车悬架仿真分析 3. 整车车悬架仿真分析 3.1 KF观测状态 3.2性能指标 4 .KF调参总结 5.文章总结 前言 对于kalman的原理介绍在上篇文章中已经做了详尽剖析&#xff0c;本篇进行实战&#xff0c;将其应用于悬架系统&#xff0c;其实…...

第二章 作业(6789B)【编译原理】

第二章 作业【编译原理】前言推荐第二章 作业678911最后前言 以下内容源自《编译原理》 仅供学习交流使用 推荐 无 第二章 作业 6 6.令文法G6为 N→D|ND D→0|1|2|3|4|5|6|7|8|9 (1)G6的语言L(G6)是什么? (2)给出句子0127、34和568的最左推导和最右推导。 &#xff08;…...

【java】连续最大和、统计回文

目录 1.连续最大和 2.统计回文 1.连续最大和 链接&#xff1a;连续最大和_牛客题霸_牛客网 (nowcoder.com) 描述&#xff1a;一个数组有 N 个元素&#xff0c;求连续子数组的最大和。 例如&#xff1a;[-1,2,1]&#xff0c;和最大的连续子数组为[2,1]&#xff0c;其和为 3 输…...

AI真的快让我们失业了,从ChatGPT到Midjourney

参考文章&#xff1a; https://mp.weixin.qq.com/s/3RdHPPhYgDfB6KY6Y9Sk2A跟AI有关的新闻&#xff0c;一个接着一个。前一天你还和往常一样进入梦乡&#xff0c;第二天醒来就能被新的AI新闻“炸弹”震得心惊。 以ChatGPT为代表的AI语言模型&#xff0c;以Midjourney为代表的…...

JVM学习 GC垃圾回收机制 (堆内存结构、GC分类、四大垃圾回收算法)

&#x1f916; 作者简介&#xff1a;努力的clz &#xff0c;一个努力编程的菜鸟 &#x1f423;&#x1f424;&#x1f425; &#x1f440; 文章专栏&#xff1a;《JVM 学习笔记》 &#xff0c;本专栏会专门记录博主在学习 JVM 中学习的知识点&#xff0c;以及遇到的问题。 …...

ChatGPT 有哪些神奇的使用方式?

ChatGPT在语言处理领域有着非常广泛的应用&#xff0c;可以用来进行语音识别、文本摘要、问答系统、机器翻译、智能客服、情感分析、智能写作等方面的应用。随着技术的不断发展和进步&#xff0c;ChatGPT在未来的应用场景和领域也将会有更加广泛的拓展和应用。ChatGPT可以应用于…...

【JavaEE】Java设计模式-单例模式(饿汉式与懒汉式)

目录 1.设计模式是啥&#xff1f; 2.单例模式 2.1什么是单例模式 2.2饿汉模式 2.3懒汉模式 3.懒汉模式与饿汉模式的区别 3.1.线程安全方面 3.2.资源加载和性能 4.如何保证懒汉模式的线程安全 1.设计模式是啥&#xff1f; 设计模式是前人经过总结&#xff0c;通过…...

(算法基础)朴素版Prim算法

适用情景在最小生成树问题当中&#xff0c;涉及到权重和最小值。并且这个图是稠密图(n^2 ~ m)的情形下时间复杂度O(N^2)算法解释先得知道一下什么是无向图的生成树&#xff0c;树总该知道的吧&#xff0c;生成树就是包含这个无向图中的n个点&#xff0c;并且有n-1条边&#xff…...

第十四届蓝桥杯三月真题刷题训练——第 23 天

目录 第 1 题&#xff1a;长草 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码&#xff1a; 思路&#xff1a; 第 2 题&#xff1a;蓝肽子序列_LCS_最长公共子序列dp问题 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码&#xff1a; 思路&am…...

基于springboot实现医院信息管理系统【源码+论文】

基于springboot实现医院信管系统演示开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xf…...

CODESYS增量式PID功能块(ST完整源代码)

增量式PID的详细算法公式和博途源代码,请参看下面的文章链接: 博途1200/1500PLC增量式PID算法(详细SCL代码)_博图scl语言pid增量编码器_RXXW_Dor的博客-CSDN博客SMART200PLC增量式PID可以参看下面这篇博文,文章里有完整的增量式PID算法公式,这里不在赘述西门子SMARTPLC增量…...

代码质量提升,代码扫描 review 之 Codacy 工具使用

目录一、什么是Codacy二、GitHub 上使用 Codacy三、Codacy上导入GitHub项目一、什么是Codacy Codacy 是用于代码 review 检测(即代码审查)的工具&#xff0c;目前支持对40多种编程语言检测&#xff0c;如 c、c、c#、java 、python、javascript 等。 Codacy 可用于 GitHub 和 …...

Centos Linux 正确安装 Redis 的方式

官方文档 Getting started with Redis | Redis 第一步 、下载源代码 源代码的下载方式有很多种&#xff0c;可以去源代码仓库下载&#xff0c;或者使用下面的命令下载 wget https://download.redis.io/redis-stable.tar.gz 第二步 、编译代码 tar -xzvf redis-stable.tar.…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...