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

双向带头链表实现

目录

一. 逻辑结构图解

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. 查找数据&#xff0c;返回节点地址 9. 指定地址后插入节点 10. 删除指定地址节点 11. 销毁链表 三.…...

黑马python-面向对象程序设计

1.定义类 class 类名&#xff1a; 代码 ….. 注意&#xff1a;类名要满足标识符命名规则&#xff0c;同时遵循大驼峰命名习惯 2.self&#xff1a; self指调用该函数的对象 3.创建对象 对象名类&#xff08;&#xff09; 4.添加获取对象属性 对象名.属性名值 5._init_()方法&…...

pod容器基础概念

一 Pod基础概念&#xff1a; ①Pod是kubernetes中最小的资源管理组件&#xff0c;Pod也是最小化运行容器化应用的资源对象。一个 Pod代表着集群中运行的一个进程。一个pod包含一个或多个容器。如&#xff1a;应用容器/业务容器&#xff08;淘 宝、京东、拼多多后台&#xff…...

AI日报:百度发布文心大模型学习机;Open-Sora 1.1可生成21秒视频;Canva可以自动剪辑视频了;超牛ComfyUI节点AnyNode来了

欢迎来到【AI日报】栏目!这里是你每天探索人工智能世界的指南&#xff0c;每天我们为你呈现AI领域的热点内容&#xff0c;聚焦开发者&#xff0c;助你洞悉技术趋势、了解创新AI产品应用。 新鲜AI产品点击了解&#xff1a;AIbase - 智能匹配最适合您的AI产品和网站 1、百度文心…...

VUE3+TS+elementplus+Django+MySQL实现从数据库读取数据,显示在前端界面上

一、前言 前面通过VUE3和elementplus创建了一个table&#xff0c;VUE3TSelementplus创建table&#xff0c;纯前端的table&#xff0c;以及使用VUE3TSelementplus创建一个增加按钮&#xff0c;使用前端的静态数据&#xff0c;显示在表格中。今天通过从后端获取数据来显示在表格…...

用c++做贪吃蛇

由于蛇是由多块蛇身组成的&#xff0c;机构体数组或者链表来存储蛇 蛇在运行过程中&#xff0c;如果吃了食物&#xff0c;那么这块食物就可以看作是新的蛇头了&#xff0c; 数组存储 存储新蛇身&#xff0c;在数组的第一个位置插入一个元素。 链表 插入和删除元素效率很高&…...

【UE5.1 角色练习】08-传送技能

前言 在上一篇&#xff08;【UE5.1 角色练习】07-AOE技能&#xff09;基础上继续实现人物通过鼠标点击然后传送技能的功能。 效果 步骤 1. 首先需要显示鼠标光标&#xff0c;我们可以在玩家控制器中勾选“显示鼠标光标” 2. 在项目设置中添加一个操作映射&#xff0c;设置按…...

力扣283题:移动零(快慢指针)

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0]示例 2: 输入: nums [0] 输出: [0…...

Java面试精粹:高级问题与解答集锦(一)

Java 高级面试问题及答案 问题1&#xff1a;Java中如何实现多线程&#xff0c;以及有哪些线程同步机制&#xff1f; 答案&#xff1a; Java实现多线程主要有两种方式&#xff1a;继承 Thread 类和实现 Runnable 接口。通过继承 Thread 类&#xff0c;可以重写 run() 方法来定…...

Yourpassword does not satisfy the current policyrequirements

mysql 新增数据库用户失败 解决方法&#xff1a; 修改校验密码策略等级 set global validate_password.policyLOW;...

解决vue3 vite打包报Root file specified for compilation问题

解决方法&#xff1a; 修改package.json打包命令 把 "build": "vue-tsc --noEmit && vite build" 修改为 "build": "vite build" 就可以了 另外关于allowJs这个问题&#xff0c;在tsconfig.json文件中配置"allowJs&qu…...

Java Swing + MySQL图书借阅管理系统

系列文章目录 Java Swing MySQL 图书管理系统 Java Swing MySQL 图书借阅管理系统 文章目录 系列文章目录前言一、项目展示二、部分代码1.Book2.BookDao3.DBUtil4.BookAddInternalFrame5.Login 三、配置 前言 项目是使用Java swing开发&#xff0c;界面设计比较简洁、适合作…...

ssm招聘信息管理系统-计算机毕业设计源码78049

摘 要 由于数据库和数据仓库技术的快速发展&#xff0c;招聘客户管理系统建设越来越向模块化、智能化、自我服务和管理科学化的方向发展。招聘客户系统对处理对象和服务对象&#xff0c;自身的系统结构&#xff0c;处理能力&#xff0c;都将适应技术发展的要求发生重大的变化。…...

eBPF可观测之网络流量控制和管理traffic control浅尝

目录 工程背景 环境准备 安装工具​​​ 安装依赖包 安装C依赖库 操作步骤 目录结构 代码展示 效果展示 拓展提升 工程背景 首先发表一个"暴论" eBPF在可观测方面的应用&#xff0c;就是各种google。 不需要学习内核&#xff0c;只要掌握ebpf开发套路。…...

Java技术精粹:高级面试问题与解答指南(二)

Java面试问题及答案 1. 什么是Java中的集合框架&#xff1f;请简述其主要接口和类。 答案&#xff1a; Java中的集合框架是一个设计用来存储和操作大量数据的统一架构。它主要由以下几个接口及其实现类组成&#xff1a; Collection: 它是最基本的集合接口&#xff0c;所有单列…...

地下停车场FM信号覆盖系统技术原理用与应用

随着我国城市化水平的快速推进与房地产的快速发展&#xff0c;城市停车场称为每栋建筑物的硬性配套建筑&#xff0c;尤其是商业综合体、医院、政府机关、机场、高铁站等场所出现了超大规模停车场&#xff0c;停放车辆可达数千辆&#xff0c;停车场的智能化与信息化水平也越来越…...

idea 出现 cpu占用100%

一、IDEA的CPU占用率过高 二、解决办法 idea安装路径bin目录 修改idea64.exe.vmoptions配置文件 原来的 -Xms128m -Xmx750m -XX:ReservedCodeCacheSize240m -XX:UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB50 修改为(IDEA优化内存配置) -Xms2048m -Xmx4096m -XX:Reser…...

如何学到数据库从入门到入土(MySQL篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人能接…...

安卓手机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语言中的实现

一、引言 二叉树是数据结构中一种非常基础且重要的树形结构&#xff0c;它的每个节点最多有两个子节点&#xff0c;通常被称为左子节点和右子节点。二叉树在计算机科学中有着广泛的应用&#xff0c;如搜索、排序、存储数据等。本文将详细介绍二叉树的基本概念、特性以及在C语言…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...