双向带头链表实现
目录
一. 逻辑结构图解
1. 节点中存储的值
2.逻辑实现
二. 各种功能实现
1. 创建节点函数
2. 初始化哨兵位
3. 尾插
4. 头插
5. 尾删
6. 头删
7. 打印链表值
8. 查找数据,返回节点地址
9. 指定地址后插入节点
10. 删除指定地址节点
11. 销毁链表
三. 完整代码
1. list.h
2. list.c
3. 测试
由于上一篇已经对链表的基本概念讲解完毕,这里就不过多赘述了
一. 逻辑结构图解
1. 节点中存储的值

qrev是上一个节点的地址
data是节点中存储的数据
next是下一个节点的位置
2.逻辑实现

第一个节点为哨兵位不存储数据
二. 各种功能实现
1. 创建节点函数
ListNode* BuyListNode(DataType x)
{ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));if (newnode == NULL){exit(-1);}newnode->data = x;newnode->next = newnode->prev = newnode;return newnode;
}
2. 初始化哨兵位
由于需要改变哨兵位本身,所以用二级指针
之后就不用改变哨兵位了所以不用用二级指针
void ListNodeInit(ListNode** pphead)
{*pphead = BuyListNode(0);
}
3. 尾插
void ListNodePushBack(ListNode* phead, DataType x)
{ListNode* tail = phead->prev;assert(phead);ListNode* newnode = BuyListNode(x);newnode->prev = phead->prev;newnode->next = phead;tail->next = newnode;//之前的尾指向现在的尾phead->prev = newnode;//头的上一个改为现在的尾
}
4. 头插
void ListNodePushFront(ListNode* head,DataType x)
{assert(head);ListNode* first = head->next;ListNode* newnode = BuyListNode(x);newnode->next = head->next;newnode->prev = head;first->prev = newnode;head->next = newnode;
}
5. 尾删
void ListNodePopBack(ListNode* head)
{assert(head);ListNode* tail=head->prev;ListNode* newtail = tail->prev;head->prev = newtail;newtail->next = head;free(tail);tail = NULL;
}
6. 头删
void ListNodePopFront(ListNode* head)
{assert(head);ListNode* first=head->next;ListNode* newfirst = first->next;head->next = newfirst;newfirst->prev = head;free(first);first = NULL;
}
7. 打印链表值
void ListNodePrint(ListNode* phead)
{assert(phead);ListNode* tmp = phead->next;while (tmp!= phead){printf("%d ", tmp->data);tmp = tmp->next;}
}
8. 查找数据,返回节点地址
ListNode* ListNodeFind(ListNode* head,DataType x)
{assert(head);ListNode* tmp = head->next;while (tmp!=head){if (tmp->data == x)return tmp;tmp = tmp->next;}return NULL;
}
9. 指定地址后插入节点
void ListNodeInsert(ListNode* pos, DataType x)
{assert(pos);ListNode* newnext = pos->next;ListNode* newnode = BuyListNode(x);newnode->prev = pos;newnode->next = newnext;pos->next = newnode;newnext->prev = newnode;}
10. 删除指定地址节点
void ListNodeErase(ListNode* pos)
{assert(pos);ListNode* posprev = pos->prev, * posnext = pos->next;posprev->next = posnext;posnext->prev = posprev;free(pos);pos = NULL;
}
11. 销毁链表
void ListNodeDestroy(ListNode* head)
{assert(head);ListNode* cur = head->next;while (cur != head){ListNode* next = cur->next;free(cur);cur = next;}
}
三. 完整代码
1. list.h
#define _CRT_SECURE_NO_WARNINGS h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int DataType;typedef struct ListNode
{DataType data;struct SList* next;struct SList* prev;
}ListNode;//初始化
void ListNodeInit(ListNode** pphead);
//尾插
void ListNodePushBack(ListNode* head, DataType x);
//打印链表
void ListNodePrint(ListNode* phead);
//头插
void ListNodePushFront(ListNode* head, DataType x);
//尾删
void ListNodePopBack(ListNode* head);
//头删
void ListNodePopFront(ListNode* head);
//查找数据
ListNode* ListNodeFind(ListNode* head, DataType x);
//指定位置后插入
void ListNodeInsert(ListNode* pos, DataType x);
//指定位置删除
void ListNodeErase(ListNode* pos);
//销毁链表
void ListNodeDestroy(ListNode* head);
2. list.c
#define _CRT_SECURE_NO_WARNINGS h#include"list.h"ListNode* BuyListNode(DataType x)
{ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));if (newnode == NULL){exit(-1);}newnode->data = x;newnode->next = newnode->prev = newnode;return newnode;
}void ListNodeInit(ListNode** pphead)
{*pphead = BuyListNode(0);
}void ListNodePushBack(ListNode* phead, DataType x)
{ListNode* tail = phead->prev;assert(phead);ListNode* newnode = BuyListNode(x);newnode->prev = phead->prev;newnode->next = phead;tail->next = newnode;//之前的尾指向现在的尾phead->prev = newnode;//头的上一个改为现在的尾
}void ListNodePrint(ListNode* phead)
{assert(phead);ListNode* tmp = phead->next;while (tmp!= phead){printf("%d ", tmp->data);tmp = tmp->next;}
}void ListNodePushFront(ListNode* head,DataType x)
{assert(head);ListNode* first = head->next;ListNode* newnode = BuyListNode(x);newnode->next = head->next;newnode->prev = head;first->prev = newnode;head->next = newnode;
}void ListNodePopBack(ListNode* head)
{assert(head);ListNode* tail=head->prev;ListNode* newtail = tail->prev;head->prev = newtail;newtail->next = head;free(tail);tail = NULL;
}void ListNodePopFront(ListNode* head)
{assert(head);ListNode* first=head->next;ListNode* newfirst = first->next;head->next = newfirst;newfirst->prev = head;free(first);first = NULL;
}ListNode* ListNodeFind(ListNode* head,DataType x)
{assert(head);ListNode* tmp = head->next;while (tmp!=head){if (tmp->data == x)return tmp;tmp = tmp->next;}return NULL;
}void ListNodeInsert(ListNode* pos, DataType x)
{assert(pos);ListNode* newnext = pos->next;ListNode* newnode = BuyListNode(x);newnode->prev = pos;newnode->next = newnext;pos->next = newnode;newnext->prev = newnode;}void ListNodeErase(ListNode* pos)
{assert(pos);ListNode* posprev = pos->prev, * posnext = pos->next;posprev->next = posnext;posnext->prev = posprev;free(pos);pos = NULL;
}void ListNodeDestroy(ListNode* head)
{assert(head);ListNode* cur = head->next;while (cur != head){ListNode* next = cur->next;free(cur);cur = next;}
}
3. 测试
#define _CRT_SECURE_NO_WARNINGS h#include"list.h"
void test()
{ListNode* head=NULL;ListNodeInit(&head);ListNodePushBack(head, 2);ListNodePushBack(head, 45);ListNodePushBack(head, 33);ListNodePushFront(head, 22);ListNodePushFront(head, 66);ListNode* find=ListNodeFind(head,33);ListNodeInsert(find, 666);ListNodePrint(head);printf("\n");//ListNodePopBack(head);ListNodeErase(find);ListNodePopFront(head);ListNodePrint(head);}int main()
{test();
}
感谢大家观看,希望可以帮到您
(づ ̄3 ̄)づ╭❤~
相关文章:
双向带头链表实现
目录 一. 逻辑结构图解 1. 节点中存储的值 2.逻辑实现 二. 各种功能实现 1. 创建节点函数 2. 初始化哨兵位 3. 尾插 4. 头插 5. 尾删 6. 头删 7. 打印链表值 8. 查找数据,返回节点地址 9. 指定地址后插入节点 10. 删除指定地址节点 11. 销毁链表 三.…...
黑马python-面向对象程序设计
1.定义类 class 类名: 代码 ….. 注意:类名要满足标识符命名规则,同时遵循大驼峰命名习惯 2.self: self指调用该函数的对象 3.创建对象 对象名类() 4.添加获取对象属性 对象名.属性名值 5._init_()方法&…...
pod容器基础概念
一 Pod基础概念: ①Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个 Pod代表着集群中运行的一个进程。一个pod包含一个或多个容器。如:应用容器/业务容器(淘 宝、京东、拼多多后台ÿ…...
AI日报:百度发布文心大模型学习机;Open-Sora 1.1可生成21秒视频;Canva可以自动剪辑视频了;超牛ComfyUI节点AnyNode来了
欢迎来到【AI日报】栏目!这里是你每天探索人工智能世界的指南,每天我们为你呈现AI领域的热点内容,聚焦开发者,助你洞悉技术趋势、了解创新AI产品应用。 新鲜AI产品点击了解:AIbase - 智能匹配最适合您的AI产品和网站 1、百度文心…...
VUE3+TS+elementplus+Django+MySQL实现从数据库读取数据,显示在前端界面上
一、前言 前面通过VUE3和elementplus创建了一个table,VUE3TSelementplus创建table,纯前端的table,以及使用VUE3TSelementplus创建一个增加按钮,使用前端的静态数据,显示在表格中。今天通过从后端获取数据来显示在表格…...
用c++做贪吃蛇
由于蛇是由多块蛇身组成的,机构体数组或者链表来存储蛇 蛇在运行过程中,如果吃了食物,那么这块食物就可以看作是新的蛇头了, 数组存储 存储新蛇身,在数组的第一个位置插入一个元素。 链表 插入和删除元素效率很高&…...
【UE5.1 角色练习】08-传送技能
前言 在上一篇(【UE5.1 角色练习】07-AOE技能)基础上继续实现人物通过鼠标点击然后传送技能的功能。 效果 步骤 1. 首先需要显示鼠标光标,我们可以在玩家控制器中勾选“显示鼠标光标” 2. 在项目设置中添加一个操作映射,设置按…...
力扣283题:移动零(快慢指针)
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0]示例 2: 输入: nums [0] 输出: [0…...
Java面试精粹:高级问题与解答集锦(一)
Java 高级面试问题及答案 问题1:Java中如何实现多线程,以及有哪些线程同步机制? 答案: Java实现多线程主要有两种方式:继承 Thread 类和实现 Runnable 接口。通过继承 Thread 类,可以重写 run() 方法来定…...
Yourpassword does not satisfy the current policyrequirements
mysql 新增数据库用户失败 解决方法: 修改校验密码策略等级 set global validate_password.policyLOW;...
解决vue3 vite打包报Root file specified for compilation问题
解决方法: 修改package.json打包命令 把 "build": "vue-tsc --noEmit && vite build" 修改为 "build": "vite build" 就可以了 另外关于allowJs这个问题,在tsconfig.json文件中配置"allowJs&qu…...
Java Swing + MySQL图书借阅管理系统
系列文章目录 Java Swing MySQL 图书管理系统 Java Swing MySQL 图书借阅管理系统 文章目录 系列文章目录前言一、项目展示二、部分代码1.Book2.BookDao3.DBUtil4.BookAddInternalFrame5.Login 三、配置 前言 项目是使用Java swing开发,界面设计比较简洁、适合作…...
ssm招聘信息管理系统-计算机毕业设计源码78049
摘 要 由于数据库和数据仓库技术的快速发展,招聘客户管理系统建设越来越向模块化、智能化、自我服务和管理科学化的方向发展。招聘客户系统对处理对象和服务对象,自身的系统结构,处理能力,都将适应技术发展的要求发生重大的变化。…...
eBPF可观测之网络流量控制和管理traffic control浅尝
目录 工程背景 环境准备 安装工具 安装依赖包 安装C依赖库 操作步骤 目录结构 代码展示 效果展示 拓展提升 工程背景 首先发表一个"暴论" eBPF在可观测方面的应用,就是各种google。 不需要学习内核,只要掌握ebpf开发套路。…...
Java技术精粹:高级面试问题与解答指南(二)
Java面试问题及答案 1. 什么是Java中的集合框架?请简述其主要接口和类。 答案: Java中的集合框架是一个设计用来存储和操作大量数据的统一架构。它主要由以下几个接口及其实现类组成: Collection: 它是最基本的集合接口,所有单列…...
地下停车场FM信号覆盖系统技术原理用与应用
随着我国城市化水平的快速推进与房地产的快速发展,城市停车场称为每栋建筑物的硬性配套建筑,尤其是商业综合体、医院、政府机关、机场、高铁站等场所出现了超大规模停车场,停放车辆可达数千辆,停车场的智能化与信息化水平也越来越…...
idea 出现 cpu占用100%
一、IDEA的CPU占用率过高 二、解决办法 idea安装路径bin目录 修改idea64.exe.vmoptions配置文件 原来的 -Xms128m -Xmx750m -XX:ReservedCodeCacheSize240m -XX:UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB50 修改为(IDEA优化内存配置) -Xms2048m -Xmx4096m -XX:Reser…...
如何学到数据库从入门到入土(MySQL篇)
本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接…...
安卓手机APP开发__Wi-Fi扫描概述
安卓手机APP开发__Wi-Fi扫描概述 目录 概述 Wi-Fi的扫描过程 限制 权限 Android 8.0 and Android 8.1: Android 9: Android 10 (API 级别 29) 和 更高版本: 扫描频率的限制 Android 8.0 and Android 8.1: Android 9: Android 10 and higher: 概述 你能使用Wi-Fi的…...
深入理解二叉树及其在C语言中的实现
一、引言 二叉树是数据结构中一种非常基础且重要的树形结构,它的每个节点最多有两个子节点,通常被称为左子节点和右子节点。二叉树在计算机科学中有着广泛的应用,如搜索、排序、存储数据等。本文将详细介绍二叉树的基本概念、特性以及在C语言…...
WSL+VSCode+Jupyter+R配置总结(2026年)
题记:网上相关的资料很多了,现阶段跟随AI也能少走很多弯路,但体验下来依旧有些细节没有被很好的提及,故写本文一方面作为自己的备忘录,一方面希望帮助更多像我一样的新手。 用了上述的配置跑了scanpy一年多了…...
STM32F407ZGT6最小系统:从原理图到PCB的实战设计解析
1. STM32F407ZGT6最小系统设计入门 第一次接触STM32F407ZGT6最小系统设计时,我也被各种专业术语和复杂的电路图搞得晕头转向。但经过几个项目的实战后,我发现只要掌握几个关键模块,设计一个稳定可靠的最小系统其实并不难。STM32F407ZGT6是STM…...
IQR四分位数法是什么?
一、核心概念:四分位数与IQR1. 四分位数(Quartiles)将一组有序数据(从小到大排列)划分为4个相等部分的三个关键分割点,分别记为:Q1(第一四分位数,25%分位数)&…...
高效低成本馈电保护电路设计与应用
1. 为什么需要馈电保护电路? 有源天线在通信系统中扮演着重要角色,但实际使用中经常会遇到一些棘手的问题。比如在野外作业时,技术人员可能会频繁插拔天线;或者在长期运行过程中,天线内部电路可能出现故障。这些情况都…...
暗黑破坏神2重制版智能辅助:自动化流程与效率提升完全指南
暗黑破坏神2重制版智能辅助:自动化流程与效率提升完全指南 【免费下载链接】botty D2R Pixel Bot 项目地址: https://gitcode.com/gh_mirrors/bo/botty 在《暗黑破坏神2:重制版》的冒险旅程中,你是否曾因重复刷怪、繁琐的装备拾取而感…...
06-AI 编程助手实战
OpenClaw + ACP:AI 编程助手实战 “让 AI 帮你写代码、调 Bug、做重构——这就是 ACP 的魔力。” 在软件开发领域,如何让 AI 真正成为程序员的得力助手,而非仅仅是「代码补全工具」?OpenClaw 给出的答案是 ACP(Agent Coding Protocol)。通过这一协议,OpenClaw 能够与业界…...
STC89C52内存告急?手把手教你优化MPU6050 DMP库,让51单片机也能流畅跑姿态解算
STC89C52内存告急?手把手教你优化MPU6050 DMP库,让51单片机也能流畅跑姿态解算 当你在STC89C52这类资源有限的51单片机上尝试运行MPU6050的DMP(Digital Motion Processor)库时,是否遇到过编译失败或运行不稳定的情况&…...
镜头背后的AI魔法:Qwen-Edit多角度编辑技术的深度探索
镜头背后的AI魔法:Qwen-Edit多角度编辑技术的深度探索 【免费下载链接】Qwen-Edit-2509-Multiple-angles 项目地址: https://ai.gitcode.com/hf_mirrors/dx8152/Qwen-Edit-2509-Multiple-angles 问题溯源:当静态图像遇见动态视角需求 在博物馆的…...
从用户视角优化:让QGC地面站的盘旋半径显示更直观的3个实用技巧
从用户视角优化:让QGC地面站的盘旋半径显示更直观的3个实用技巧 在无人机飞行任务规划中,盘旋半径的准确显示直接关系到飞行安全和任务执行效率。QGroundControl(QGC)作为业界领先的开源地面站软件,其功能强大但某些细…...
3步解决字幕处理90%的麻烦:BiliBiliCCSubtitle效率革命
3步解决字幕处理90%的麻烦:BiliBiliCCSubtitle效率革命 【免费下载链接】BiliBiliCCSubtitle 一个用于下载B站(哔哩哔哩)CC字幕及转换的工具; 项目地址: https://gitcode.com/gh_mirrors/bi/BiliBiliCCSubtitle 开篇:三个真实场景的效率反差 场景…...
