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

双向链表的实现(详解)

目录

  • 前言
  • 初始化
  • 双向链表的结构
  • 为双向链表的节点开辟空间
  • 头插
  • 尾插
  • 打印链表
  • 尾删
  • 头删
  • 查找
  • 指定位置之后的插入
  • 删除pos节点
  • 销毁双向链表

前言

链表的分类: 带头 不带头 单向 双向 循环 不循环
一共有 (2 * 2 * 2) 种链表

带头指的是:带有哨兵位节点
哨兵位(头结点):可以放随机数据,哨兵位指向的下一个节点就是我们的第一个有效节点,我们指的头节点是哨兵位
在这里插入图片描述
单向:指针只能从前向后遍历
双向:指针既可以从前向后遍历又可以从后向前遍历
循环:可以通过尾节点找到头节点,从而达到循环
在这里插入图片描述

主要使用的链表是单链表和双向链表
单链表:不带头单向不循环
双向链表:带头双向循环

初始化

ListNode* TLInit()
{ListNode* phead = ListByNode(-1);//ListByNode后面会介绍//为头节点开辟一个空间,并将头结点指向的值赋值为-1return phead;//将开辟出的头节点返回我们的主函数,主函数中的头节点就知道我们有一个哨兵位了
}
//初始化
void TLInit(ListNode** pphead)
{//给双向链表创建一个哨兵位*pphead = ListByNode(-1);
}

初始化有两种写法,第二种写法也是可行的,但是用第一种,可以使得接口一致,都是一级指针,使用者也会更方便的使用,不用去记忆那个要用一级指针还是二级指针

双向链表的结构

//定义双向链表的结构
typedef int DataType;
typedef struct ListNode//双向链表
{DataType x;//双向链表中的数据struct ListNode* next;//指向后一个节点,后继指针struct ListNode* prev;//指向前一个节点,前驱指针
}ListNode;

为双向链表的节点开辟空间

ListNode* ListByNode(DataType x)
{ListNode* node = (ListNode*)malloc(sizeof(ListNode));if (node == NULL){perror("malloc");return NULL;}//开辟成功node->next = node->prev = node;//初始化一个哨兵位的下一个节点和前一个节点指向的是自己node->x = x;return node;
}

头插

//头插
//在第一个有效节点之前插入一个节点
void TLPushFront(ListNode* phead,DataType x)
//用一级指针为了不改变原链表的哨兵位
{assert(phead);//断言一下是不是空链表ListNode* newnode = ListByNode(x);ListNode* pcur = phead->next;newnode->next = pcur;newnode->prev = phead;pcur->prev = newnode;phead->next = newnode;}

在这里插入图片描述

尾插

//尾插
//在头节点之后或者之前插入
//因为在哨兵位前,哨兵位的prev指向尾结点,尾结点的next指向哨兵位
void TLPushBack(ListNode* phead,DataType x)
{assert(phead);//链表不为空ListNode* newnode = ListByNode(x);//为尾插的节点开辟空间ListNode* pcur = phead->prev; newnode->next = phead;newnode->prev = pcur;pcur->next = newnode;phead->prev = newnode;
}

在这里插入图片描述

打印链表

//打印链表
void TLPrint(ListNode* phead)
{ListNode* pcur = phead->next;while (pcur != phead){printf("%d->", pcur->x);pcur = pcur->next;}printf("\n");
}

尾删

//尾删
//注意哨兵位不能被删除,所以理论上至少有一个节点,才能够删除
void TLPopBack(ListNode* phead)
{assert(phead&&phead->next!=phead);ListNode* pcur = phead->prev;ListNode* del = pcur->prev;del->next = phead;phead->prev = del;free(pcur);pcur = NULL;}

在这里插入图片描述

头删

//头删
//注意哨兵位不能被删除,所以理论上至少有一个节点,才能够删除
void TLPopFront(ListNode* phead)
{assert(phead&&phead->next!=phead);//phead不能为空ListNode* pcur = phead->next;pcur->next->prev = phead;phead->next = pcur->next;free(pcur);pcur = NULL;}

在这里插入图片描述

查找

//查找 x 数据的位置并返回
ListNode* SLFind(DataType x,ListNode* phead)
{ListNode* pcur = phead->next;while (pcur != phead){if (pcur->x == x){return pcur;//找到了}pcur = pcur->next;}return NULL;//找不到了
}

指定位置之后的插入

//指定位置之后的插入
//知道了pos节点,就知道了pos之前的数和之后的数
//指定位置之后的插入和指定位置之前的插入是一样的
void TLInsert(ListNode* pos,DataType x)
{assert(pos);//插入的pos位置不能为空ListNode* newnode = ListByNode(x);//为插入的数据开辟空间ListNode* pcur = pos->next;newnode->next = pcur;newnode->prev = pos;pos->next = newnode;pcur->prev = newnode;}

在这里插入图片描述

删除pos节点

//删除pos节点
void Erase(ListNode* pos)
{assert(pos);//理论上pos不能为phead,因为phead不能被删除,它是双向链表pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;}

在这里插入图片描述

销毁双向链表

//销毁双向链表
void LTDestroy(ListNode* phead)
{assert(phead);//phead不为空,才销毁,为空,不用销毁//销毁时phead也要释放(销毁)ListNode* pcur = phead->next;ListNode* next = pcur->next;while (pcur != phead){next = pcur->next;free(pcur);pcur = next;}//出来后pcur指向pheadfree(phead);phead = NULL;
}

相关文章:

双向链表的实现(详解)

目录 前言初始化双向链表的结构为双向链表的节点开辟空间头插尾插打印链表尾删头删查找指定位置之后的插入删除pos节点销毁双向链表 前言 链表的分类: 带头 不带头 单向 双向 循环 不循环 一共有 (2 * 2 * 2) 种链表 带头指的是:带有哨兵位节点 哨兵位&a…...

SpringBoot项目中如何使用校验工具

用到hutool提供的校验方法与java提供的校验方法 1. 声明数据 String str "123" String regex "^123456$" Boolean is1_6 mismatch(str, regex);2. 定义校验方法 // 校验是否不符合正则格式 private static boolean mismatch(String str, String rege…...

AI预测小分子与蛋白的相关特征: MegaMolBART, MoFlow,ESM-1, ESM-2

1、小分子:MegaMolBART, MoFlow 1)MegaMolBART https://github.com/NVIDIA/MegaMolBART 基于 SMILES 的小分子药物发现与化学信息学深度学习模型。 2)MoFlow https://github.com/calvin-zcx/moflow 用flow流方式分子生成 2、蛋白质:ESM-1, ESM-2 https://github.com/fa…...

基于深度学习的花卉检测系统(含PyQt界面)

基于深度学习的花卉检测系统(含PyQt界面) 前言一、数据集1.1 数据集介绍1.2 数据预处理 二、模型搭建三、训练与测试3.1 模型训练3.2 模型测试 四、PyQt界面实现参考资料 前言 本项目是基于swin_transformer深度学习网络模型的花卉检测系统,…...

深度学习图像处理基础工具——opencv 实战信用卡数字识别

任务 信用卡数字识别 穿插之前学的知识点 形态学操作 模板匹配 等 总体流程与方法 1.有一个模板 2 用轮廓检测把模板中数字拿出来 外接矩形(模板和输入图像的大小要一致 )3 一系列预处理操作 问题的解决思路 1.分析准备:准备模板&#…...

【HBase】HBase高性能架构:如何保证大规模数据的高可用性

HBase高性能原理 HBase 能够提供高性能的数据处理能力,主要得益于其设计和架构的几个关键方面。这些设计特点使得 HBase 特别适合于大规模、分布式的环境中进行高效的数据读写操作。以下是 HBase 高性能的主要原因: 1. 基于列的存储 HBase 是一个列式…...

JAVA基础两个项目案例代码

1.JAVA使用ArrayList上架菜品案例 视频参考链接 创建一个Food.java类 package org.example;// 菜品类 public class Food {private String name; // 菜品名private double price; // 价格private String desc; // 菜品描述public Food() {}public Food(String name, Double …...

asp.net core 网页接入微信扫码登录

创建微信开放平台账号&#xff0c;然后创建网页应用 获取appid和appsecret 前端使用的vue&#xff0c;安装插件vue-wxlogin 调用代码 <wxlogin :appid"appId" :scope"scope" :redirect_uri"redirect_uri"></wxlogin> <scri…...

【板栗糖GIS】如何给微软拼音输入法加上小鹤双拼

【板栗糖GIS】如何给微软拼音输入法加上小鹤双拼 用过在注册表里新建的方法&#xff0c;结果弄完没有出现小鹤双拼方案&#xff0c;想到了自己写reg表 目录 1. 新建一个txt文件 2. 把.txt的后缀名改成.reg&#xff0c;双击运行 3. 在设置中找到微软输入法-常规 1. 新建一个…...

如何解决微信小程序无法使用css3过度属性transition

由于微信小程序不支持CSS3过度属性transition,所以我们需要利用微信小程序api进行画面过度的展示 首先是官方示例: wxml: <view animation="{{animationData}}" style="background:red;height:100rpx;width:100rpx"></view> js: Page(…...

【软件设计师知识点】九、网络与信息安全基础知识

文章目录 计算机网络的概念网络分类网络拓扑结构网络体系结构ISO/OSI 7层参考模型TCP/IP 4层模型TCP/IP 协议族应用层协议传输层协议网络层协议IP 地址IPV4 数据报IP 地址分类子网划分子网掩码IPv6地址...

广东省道路货物运输资格证照片回执可手机线上办理

广东省道路运输资格证是从事道路运输业务、危险品道路运输人员的必要证件&#xff0c;而在办理该证件的过程中&#xff0c;驾驶员照片回执是一项必不可少的材料。随着科技的发展和移动互联网的普及&#xff0c;现在办理驾驶员照片回执已经不再需要亲自前往照相馆&#xff0c;而…...

【微信小程序——案例——本地生活(列表页面)】

案例——本地生活&#xff08;列表页面&#xff09; 九宫格中实现导航跳转——以汽车服务为案例&#xff08;之后可以全部实现页面跳转——现在先实现一个&#xff09; 在app.json中添加新页面 修改之前的九宫格view改为navitage 效果图&#xff1a; 动态设置标题内容—…...

【设计模式】SOLID设计原则

1、什么是SOLID设计原则 SOLID 是面向对象设计中的五个基本设计原则的首字母缩写&#xff0c;它们是&#xff1a; 单一职责原则&#xff08;Single Responsibility Principle&#xff0c;SRP&#xff09;&#xff1a; 类应该只有一个单一的职责&#xff0c;即一个类应该有且只…...

基于java+springboot+vue实现的智能停车计费系统(文末源码+Lw+ppt)23-30

摘 要 随着人们生活水平的高速发展&#xff0c;智能停车计费信息管理方面在近年来呈直线上升&#xff0c;人们也了解到智能停车计费的实用性&#xff0c;因此智能停车计费的管理也逐年递增&#xff0c;智能停车计费信息的增加加大了在管理上的工作难度。为了能更好的维护智能…...

IntelliJ IDEA 2022.3.2 解决decompiled.class file bytecode version:52.0(java 8)

1 背景 使用idea 打开一个Kotlin语言编写的demo项目&#xff0c;该项目使用gradle构建。其gradle文件如下&#xff1a; plugins {id javaid org.jetbrains.kotlin.jvm version 1.8.20 } group me.administrator version 1.0-SNAPSHOTrepositories {mavenCentral()jcenter()…...

C++11 设计模式1. 模板方法(Template Method)模式学习。UML图

一 什么是 "模板方法&#xff08;Template Method&#xff09;模式" 在固定步骤确定的情况下&#xff0c;通过多态机制在多个子类中对每个步骤的细节进行差异化实现&#xff0c;这就是模板方法模式能够达到的效果。 模板方法模式属于&#xff1a;行为型模式。 二 &…...

HarmonyOS实战开发-自定义分享

介绍 自定义分享主要是发送方将文本&#xff0c;链接&#xff0c;图片三种类型分享给三方应用,同时能够在三方应用中展示。本示例使用数据请求 实现网络资源的获取&#xff0c;使用屏幕截屏 实现屏幕的截取&#xff0c;使用文件管理 实现对文件&#xff0c;文件目录的管理&…...

Spring源码刨析之配置文件的解析和bean的创建以及生命周期

public void test1(){XmlBeanFactory xmlBeanFactory new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));user u xmlBeanFactory.getBean("user",org.xhpcd.user.class);// System.out.println(u.getStu());}先介绍一个类XmlBeanFac…...

如何使用 Grafana 监控文件系统状态

当 JuiceFS 文件系统部署完成并投入生产环境&#xff0c;接下来就需要着手解决一个非常重要的问题 —— 如何实时监控它的运行状态&#xff1f;毕竟&#xff0c;它可能正在为关键的业务应用或容器工作负载提供持久化存储支持&#xff0c;任何小小的故障或性能下降都可能造成不利…...

如何在Windows电脑上轻松安装安卓应用:5步完成轻量级跨平台部署

如何在Windows电脑上轻松安装安卓应用&#xff1a;5步完成轻量级跨平台部署 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否想在Windows电脑上运行安卓应用&…...

Nevis‘22基准:评估持续学习模型的计算效率与知识迁移能力

1. 项目概述&#xff1a;为什么我们需要一个全新的终身学习基准&#xff1f;在计算机视觉乃至整个机器学习领域&#xff0c;我们正面临一个日益尖锐的矛盾&#xff1a;一方面&#xff0c;我们希望模型能够像人类一样&#xff0c;在漫长的时间里持续学习新知识&#xff0c;不断进…...

xhs签名验证机制详解:如何绕过小红书反爬虫系统的终极指南

xhs签名验证机制详解&#xff1a;如何绕过小红书反爬虫系统的终极指南 【免费下载链接】xhs 基于小红书 Web 端进行的请求封装。https://reajason.github.io/xhs/ 项目地址: https://gitcode.com/gh_mirrors/xh/xhs 在小红书数据爬取领域&#xff0c;xhs签名验证机制是开…...

西门子S7-1200 PLC编程避坑指南:从振荡电路到浮点数计算,新手最常犯的5个错误

西门子S7-1200 PLC编程实战避坑手册&#xff1a;从逻辑陷阱到数据精度 第一次接触西门子S7-1200 PLC编程时&#xff0c;我对着闪烁的指示灯发呆了半小时——明明按照手册写的梯形图&#xff0c;为什么定时器就是不工作&#xff1f;后来才发现是TON指令的PT参数单位理解错误。这…...

python网上书店系统vue

目录技术栈选择前端模块划分后端API设计关键实现细节开发流程示例代码片段项目技术支持源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作技术栈选择 前端采用Vue 3&#xff08;Composition API&#xff09; TypeScript Vite构建工具&#…...

CANopen协议核心机制与工业自动化应用实践

1. CANopen协议的核心机制解析 CANopen协议作为工业自动化领域的通信标准&#xff0c;其核心在于三个关键机制&#xff1a;对象字典、网络管理&#xff08;NMT&#xff09;以及过程数据对象&#xff08;PDO&#xff09;/服务数据对象&#xff08;SDO&#xff09;。理解这些机制…...

基于SAP CAP与RAG技术构建企业级智能问答系统实战指南

1. 项目概述&#xff1a;当企业级应用遇上生成式AI最近在做一个企业级应用的智能问答功能&#xff0c;客户要求能基于他们内部的海量文档&#xff08;PDF、Word、Excel&#xff09;进行精准回答&#xff0c;而不是让大模型“自由发挥”。这让我想起了SAP官方在GitHub上开源的那…...

别再用LoadRunner了!用JMeter+阿里云PTS搞定mPaaS网关全链路压测(附MGSJMeterExt插件实战)

从LoadRunner到JMeterPTS&#xff1a;mPaaS网关压测的高效实战指南 在移动应用性能优化的战场上&#xff0c;压力测试一直是确保系统稳定性的关键环节。传统工具如LoadRunner虽然功能强大&#xff0c;但面对mPaaS这类移动网关架构时&#xff0c;其高昂的授权成本、复杂的适配流…...

无人机雷达与LiDAR协同监测土壤湿度技术解析

1. 无人机雷达与LiDAR协同监测土壤湿度的技术原理在精准农业领域&#xff0c;土壤湿度监测一直面临着植被遮挡带来的技术挑战。传统的地面传感器网络虽然精度较高&#xff0c;但存在部署成本高、维护困难等问题&#xff1b;而光学遥感又难以穿透茂密的作物冠层。无人机载雷达与…...

Qt QColumnView实战:手把手教你打造一个macOS Finder风格的文件浏览器

Qt QColumnView实战&#xff1a;从零构建macOS风格文件浏览器 在桌面应用开发中&#xff0c;文件浏览器的实现一直是开发者面临的经典挑战。传统方案往往采用QTreeView或QListView&#xff0c;但它们难以还原macOS Finder那种优雅的列式导航体验。这正是QColumnView的用武之地—…...