双向带头链表实现

目录

一. 逻辑结构图解

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 ̄)づ╭❤~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/653974.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue实现附件下载 获取到接口的图片,设置宽度100%样式

一、vue实现附件下载&#xff0c;使用a链接 <a class"btn flex_center" target"_blank" :href"localImgSrc(goodsDetail.attachment)" :download"localImgSrc(goodsDetail.attachment)" >立即下载 </a>二、 获取到接口…

七大获取免费https的方式

想要实现https访问最简单有效的的方法就是安装SSL证书。只要证书正常安装上以后&#xff0c;浏览器就不会出现网站不安全提示或者访问被拦截的情况。下面我来教大家怎么去获取免费的SSL证书&#xff0c;又如何安装证书实现https访问。 一、选择免费SSL证书提供商 有多家机构提…

vue3(一):Vue3简介、创建vue3工程、Vue3中的响应式

目录 一.Vue3简介 1.性能提升 2.源码升级 3.拥抱ts 4.新特性 &#xff08;1&#xff09;Composition API&#xff08;组合API&#xff09;&#xff1a; &#xff08;2&#xff09;新的内置组件&#xff1a; &#xff08;3&#xff09;其他改变&#xff1a; 二.创建vue…

【计算机视觉(4)】

基于Python的OpenCV基础入门——色彩空间转换 色彩空间简介HSV色彩空间GRAY色彩空间色彩空间转换 色彩空间转换代码实现: 色彩空间简介 色彩空间是人们为了表示不同频率的光线的色彩而建立的多种色彩模型。常见的色彩空间有RGB、HSV、HIS、YCrCb、YUV、GRAY&#xff0c;其中最…

BLE蓝牙模块在车联网中的智能开锁、数据监控应用

随着科技的不断发展&#xff0c;车联网已经成为了汽车行业的一个热门话题。在这个领域中&#xff0c;BLE蓝牙模块发挥着重要的作用&#xff0c;特别是在智能开锁和数据监控方面的应用。本文将详细介绍BLE蓝牙模块在这两个方面的应用及其优势。   一、智能开锁   1.车辆远程…

从华为云OBS到AWS云上S3:迁移及相关事项

随着云计算的快速发展&#xff0c;企业越来越倾向于将数据存储和管理移到云端。华为云的对象存储服务&#xff08;OBS&#xff09;和亚马逊云服务&#xff08;AWS&#xff09;上的简单存储服务&#xff08;S3&#xff09;是两个备受欢迎的选择。对于那些考虑从华为云OBS迁移到A…

工商银行异地卡兑换泰铢的流程

本文介绍在国内的工商银行&#xff0c;通过现金或银行卡兑换泰国铢等外国货币的纸币或硬币的方法。 最近&#xff0c;准备到泰国旅行&#xff0c;所以需要兑换一些泰铢&#xff0c;防止下飞机到当地后找不到汇率合适、兑换方便的换钱的地方。其中&#xff0c;因为对比发现工商银…

SQL试题使得每个学生 按照姓名的字⺟顺序依次排列 在对应的⼤洲下⾯

学⽣地理信息报告 学校有来⾃亚洲、欧洲和美洲的学⽣。 表countries 数据如下&#xff1a; namecontinentJaneAmericaPascalEuropeXiAsiaJackAmerica 1、编写解决⽅案实现对⼤洲&#xff08;continent&#xff09;列的 透视表 操作&#xff0c;使得每个学生 按照姓名的字⺟顺…

Django5+React18前后端分离开发实战14 React-Router6 入门教程

使用nodejs18 首先&#xff0c;将nodejs切换到18版本&#xff1a; nvm use 18创建项目 npm create vitelatest zdpreact_basic_router_dev -- --template react cd zdpreact_basic_router_dev npm install react-router-dom localforage match-sorter sort-by npm run dev此…

Python-3.12.0文档解读-内置函数ord()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 概述 语法 参数 返回值 示例 注意事项 应用场景 记忆策略 常用场景…

JD3-40/23漏电继电器 AC220V 50-500mA 0.1s 导轨安装

系列型号&#xff1a; JD3-40/13漏电继电器JD3-40/23漏电继电器JD3-40/33漏电继电器JD3-40/43漏电继电器 JD3-70/13漏电继电器JD3-70/23漏电继电器JD3-70/33漏电继电器JD3-70/43漏电继电器 JD3-100/23漏电继电器JD3-100/43漏电继电器JD3-100/33漏电继电器JD3-100/13漏电继电…

ARM架构与分类

ARM架构&#xff0c;曾称进阶精简指令集机器&#xff08;Advanced RISC Machine&#xff09;更早称作Acorn RISC Machine&#xff0c;是一个32位精简指令集&#xff08;RISC&#xff09;处理器架构。 主要是根据FPGA zynq-7000的芯片编写的知识思维导图总结&#xff0c;没有会…

【NumPy】全面解析NumPy随机数生成器:使用numpy.random的实用技巧

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

【软件设计师】算法

1、算法的效率 时间复杂度:程序从开始到结束所需要的时间 空间复杂度&#xff1a;算法在运行过程中临时占用存储空间大小的度量 时间渐近复杂度&#xff1a;时间复杂度由最高次幂决定(判断大小技巧&#xff1a;将n10代入&#xff09; O(log2 n):二分查找法 O(n&#xff09;:for…

720VR三维立体小程序源码系统 手机电脑端自适应 前后端分离 带完整的安装代码包以及搭建教程

系统概述 720VR 三维立体小程序源码系统是基于先进的技术和理念打造而成的综合性平台。它融合了虚拟现实技术、移动互联网技术以及计算机编程技术&#xff0c;旨在为用户提供沉浸式的 720 度全景体验。 该系统的设计充分考虑了用户的需求&#xff0c;无论是在手机端还是电脑端…

从零学爬虫:使用比如说说解析网页结构

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、网页结构概述 示例&#xff1a;查看网页结构 三、使用比如说说解析网页 1.…

抖音小程序如何生成二维码

1.页面结构 <image src{{imgUrl}}></image>2.代码结构 onLoad(options) {if (options.param) {var qrCode 13246897451257 //传入生成二维码的字符串this.generateQRCode(qrCode);}},//调起第三方库qrCodegenerateQRCode(text) {//调用了qrCode里面的apiconst api…

uniapp App去除iOS底部安全区域白边

未设置的情况下&#xff0c;iOS底部安全区域白边 如图&#xff1a; 去除方法&#xff1a; 在 mainfest.json 中加入一下代码&#xff1a; "safearea" : {"bottom" : {"offset" : "none"} }, 去除效果展示&#xff1a;

HTTP请求拦截器链

文章目录 HTTP请求拦截器链需求定义写一个Controller方法接口写三个http请求拦截器把拦截器加入到配置中&#xff0c;并且配置拦截规则在postman里面发送请求&#xff0c;看下测试结果是否正确 HTTP请求拦截器链 需求定义 我们写一个包含三个HTTP请求拦截器的拦截器链&#x…

盲人无障碍设施建设:科技之光照亮前行之路

在这个快速发展的时代&#xff0c;科技的每一次进步都在悄然改变着我们的生活&#xff0c;尤其在提升特殊群体生活质量方面&#xff0c;展现出前所未有的力量。今天&#xff0c;让我们聚焦于盲人无障碍设施建设这一重要话题&#xff0c;通过一款名为“蝙蝠避障”的辅助软件&…