当前位置: 首页 > 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语言…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...