带头双向循环链表的实现及注释教学

首先需要借助三个文件        test.c   list.h   list.c

目录

list.h

list.c

test.c


list.h

用于声明函数及创建结构体、包含头文件

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int LTDataType;
typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}LTNode;LTNode* LTInit();
void LTPrint(LTNode* phead);bool LTEmpty(LTNode* phead);
void LTPushBack(LTNode* phead, LTDataType x);
void LTPushFront(LTNode* phead, LTDataType x);
void LTPopBack(LTNode* phead);
void LTPopFront(LTNode* phead);LTNode* LTFind(LTNode* phead, LTDataType x);		//查找要返回指针// 在pos之前插入
void LTInsert(LTNode* pos, LTDataType x);		//插入要传指针
// 删除pos位置的值
void LTErase(LTNode* pos);		//删除要传指针
void LTDestroy(LTNode* phead);	//需要人为置空

list.c

用于函数功能的实现

#include"List.h"LTNode* BuyLTNode(LTDataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));	//开辟if (newnode == NULL)	//判断{perror("malloc fail");return NULL;}newnode->data = x;newnode->next = NULL;	//置空newnode->prev = NULL;	//置空return newnode;		//返回新节点的地址
}LTNode* LTInit()			//初始化
{LTNode* phead = BuyLTNode(-1);	//指针接收新开辟的空间phead->next = phead;phead->prev = phead;return phead;
}void LTPrint(LTNode* phead)
{assert(phead);printf("guard<==>");LTNode* cur = phead->next;		//遍历节点,cur都是从有效节点开始。while (cur != phead){printf("%d<==>", cur->data);cur = cur->next;}printf("\n");
}bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;		//为空return真
}//1.链接尾 2.成环	void LTPushBack(LTNode* phead, LTDataType x)	//目的是尾插,尾节点可以直接找到!
{assert(phead);LTInsert(phead, x);		//在哨兵位之前插入//LTNode* tail = phead->prev;	//找尾指针//LTNode* newnode = BuyLTNode(x);	//接收新建的节点//链接“尾”和新节点//tail->next = newnode;		//newnode->prev = tail;//成环//newnode->next = phead;	//尾的下一个是头//phead->prev = newnode;	//头的上一个是尾
}//void LTPushFront(LTNode* phead, LTDataType x)
//{
//	assert(phead);
//	LTNode* newnode = BuyLTNode(x);
//
//	newnode->next = phead->next;
//	phead->next->prev = newnode;
//
//	phead->next = newnode;
//	newnode->prev = phead;
//}//不用管有没有有效节点void LTPushFront(LTNode* phead, LTDataType x)
{/*assert(phead);LTNode* newnode = BuyLTNode(x);//当只有哨兵位时,phead->next  与 phead->prev 就是 pheadLTNode* first = phead->next;	//防止找不到下一个,先记录他!(原来的首节点)phead->next = newnode;newnode->prev = phead;newnode->next = first;first->prev = newnode;*/LTInsert(phead->next, x);			//第一个有效节点之前插入
}
void LTPopBack(LTNode* phead)		//所有删除都需要判断有没有有效节点
{assert(phead);assert(!LTEmpty(phead));	//判断有没有有效节点。	(!真   就是    假)LTErase(phead->prev);/*LTNode* tail = phead->prev;	//找尾LTNode* tailPrev = tail->prev;	//找prevfree(tail);		//free//链接tailPrev->next = phead;		phead->prev = tailPrev;*/}//void LTPopFront(LTNode* phead)
//{
//	assert(phead);
//	assert(!LTEmpty(phead));
//
//	LTNode* next = phead->next;
//
//	/*phead->next = next->next;
//	phead->next->prev = phead;
//	free(next);*/
//
//	phead->next = next->next;
//	next->next->prev = phead;
//	free(next);
//}void LTPopFront(LTNode* phead)
{assert(phead);assert(!LTEmpty(phead));	//一定要有一个节点! LTErase(phead->next);//LTNode* first = phead->next;		//借助first 和 second 表示节点//LTNode* second = first->next;//链接//phead->next = second;//second->prev = phead;//释放//free(first);
}LTNode* LTFind(LTNode* phead, LTDataType x)			//查找绑定修改、插入
{assert(phead);LTNode* cur = phead->next;	//从有效节点开始查找while (cur != phead)	//遍历所有{if (cur->data == x){return cur;		//返回指针}cur = cur->next;}return NULL;		//找不到返回空
}// 在  pos 之前插入, 传pos指针
void LTInsert(LTNode* pos, LTDataType x)		//插入(头插、尾插复用insert)
{assert(pos);LTNode* prev = pos->prev;LTNode* newnode = BuyLTNode(x);		//开空间// prev newnode posprev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}// 删除  pos   位置  的值
void LTErase(LTNode* pos)		//要么传phead,检查不能删除phead,要么再检查
{assert(pos);LTNode* posPrev = pos->prev;LTNode* posNext = pos->next;posPrev->next = posNext;posNext->prev = posPrev;free(pos);		//free空间
}void LTDestroy(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;		//头节点开始while (cur != phead)	//!= 哨兵位{LTNode* next = cur->next;	//建立一个next,指向下一个节点!free(cur);cur = next;		//通过cur = next改变cur迭代}free(phead);	//释放哨兵位//没必要置空phead,形参改变不会影响实参。如果想置空,则要传二级指针!
}

test.c

用于测试函数功能

注意点

此链表的强大之处在于:当只有一个有效节点时,仍能按照一种情况完成所有增删查改!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 2908. 元素和最小的山形三元组 I。(通过JavaScript实现)

给你一个下标从 0 开始的整数数组 nums 。 如果下标三元组 (i, j, k) 满足下述全部条件&#xff0c;则认为它是一个 山形三元组 &#xff1a; i < j < knums[i] < nums[j] 且 nums[k] < nums[j] 请你找出 nums 中 元素和最小 的山形三元组&#xff0c;并返回其 …

Vue3 使用 v-bind 动态绑定 CSS 样式

在 Vue3 中&#xff0c;可以通过 v-bind 动态绑定 CSS 样式。 语法格式&#xff1a; color: v-bind(数据); 基础使用&#xff1a; <template><h3 class"title">我是父组件</h3><button click"state !state">按钮</button>…

STL容器vector

vector存放基本数据类型 STL中最常用的容器就是vector&#xff0c;可以理解成为数组。 需要掌握如何向vector容器插入数据、遍历vector。 #include <iostream> #include <Windows.h> #include <vector> #include <algorithm> // 使用STL提供的遍历算法…

牛客NC31 第一个只出现一次的字符【simple map Java,Go,PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/1c82e8cf713b4bbeb2a5b31cf5b0417c 核心 Map参考答案Java import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可*…

INA350ABSIDDFR 仪表放大器 单路低功耗 TSOT-23-8

NA350ABSIDDFR 是一款高精度、低功耗、单片式精密运算放大器。它具有出色的直流精度和低失调电压&#xff0c;适用于需要高精度信号处理的应用。这款产品广泛应用于各种领域&#xff0c;如工业控制、医疗设备、测试与测量设备以及通信系统等。 制造商: Texas Instruments …

思维题,LeetCode331. 验证二叉树的前序序列化

一、题目 1、题目描述 序列化二叉树的一种方法是使用 前序遍历 。当我们遇到一个非空节点时&#xff0c;我们可以记录下这个节点的值。如果它是一个空节点&#xff0c;我们可以使用一个标记值记录&#xff0c;例如 #。 例如&#xff0c;上面的二叉树可以被序列化为字符串 &quo…

3.恒定乘积自动做市商算法及代码

中心化交易所的安全风险 在中心化交易所中注册账户时&#xff0c;是由交易所生成一个地址&#xff0c;用户可以向地址充币&#xff0c;充到地址之后交易所就会根据用户充币的数量显示在管理界面中。但是充币的地址是掌管在交易所之中的&#xff0c;资产的控制权还是在交易所。…

[数据集][目标检测]公共场所危险物品检测数据集VOC+YOLO格式1431张6类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1431 标注数量(xml文件个数)&#xff1a;1431 标注数量(txt文件个数)&#xff1a;1431 标注…

从0开始搭建基于VUE的前端项目(二) 安装和配置element-ui组件库

版本和地址 ElementUI 2.15.14 (https://element.eleme.io/)按需引入的插件 babel-plugin-component(1.1.1) https://github.com/ElementUI/babel-plugin-component安装 npm install element-ui完整引入(不建议) 这种方式最后打包的源文件很大,造成网络资源的浪费main.jsimpo…

dubbo的分布式事务原理、Java如何实现dubbo的分布式事务

1、dubbo的分布式事务原理 Dubbo支持分布式事务的原理主要有两种方式&#xff1a;基于本地消息表和基于可靠消息服务。 1、基于本地消息表 1.Dubbo在服务提供者和消费者之间插入一个本地消息表来记录事务消息。 2.在调用远程服务前&#xff0c;Dubbo会将事务消息插入到本地消…

MFC(二)集成基础控件

目录 OnCreateCStatic【标签&#xff0c;图片】CEdit【文本框&#xff0c;密码框&#xff0c;数值框&#xff0c;文本区】CButton【按钮&#xff0c;单选按钮&#xff0c;多选按钮】CComboBox【下拉列表&#xff0c;列表】CSliderCtrl【滑动条】CListCtrl【表格】CAnimateCtrl【…

C语言分支循环探秘:解锁编程逻辑的无限可能 篇章1

目录 1.if语句 2.关系操作符 3.条件操作符 4.逻辑操作符&#xff1a;&&&#xff0c;||&#xff0c;&#xff01; 5.switch语句 6.while循环 7.for循环 8.do-while循环 9.break和continue语句 10.循环的嵌套 11.goto 导入 C语言是结构化的程序设计语言&…

数字化服务升级:数字乡村改善农民生活质量

随着信息技术的迅猛发展&#xff0c;数字化浪潮已经深入社会的各个角落&#xff0c;为人们的生活带来了翻天覆地的变化。在乡村地区&#xff0c;数字化服务的升级正在逐步改变农民的生活方式&#xff0c;提高他们的生活质量。本文将围绕数字化服务升级&#xff0c;探讨数字乡村…

【蓝桥杯选拔赛真题51】C++百位上的数字 第十四届蓝桥杯青少年创意编程大赛 算法思维 C++编程选拔赛真题解析

目录 C百位上的数字 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、推荐资料 C百位上的数字 第十四届蓝桥杯青少年创意编程大赛C选拔赛真题 一、题目要求 1、编程实现 给定一个三位数&#xff0c…

京东云免费服务器申请入口,2024年最新免费云主机

京东云服务器免费6月申请入口 jdyfwq.com 在京东云免费云主机申请页面&#xff0c;免费云服务器配置为云主机2核4G5M和轻量云主机2C2G可以申请免费使用&#xff0c;目前京东云免费云服务器申请时长从之前的6个月缩短到1个月&#xff0c;如下图&#xff1a; 京东云免费云主机 云…

CPU Cache

在嵌入式开发中&#xff0c;"cache"通常指的是处理器内部的缓存&#xff0c;特别是指的是CPU缓存。CPU缓存是一种高速缓存存储器&#xff0c;用于暂时存储处理器频繁访问的数据和指令&#xff0c;以加快对这些数据和指令的访问速度。 CPU缓存通常包括以下几种&#…

Java中验证码功能的解决方案(二)

本系列文章简介&#xff1a; 在本系列文章中&#xff0c;我们将介绍如何使用Java生成验证码&#xff0c;并提供一些实际应用中的最佳实践和建议。无论选择哪种方案&#xff0c;都需要仔细考虑应用的具体需求&#xff0c;并根据实际情况进行调整和优化。 欢迎大家订阅《Java技术…

设计模式学习笔记 - 设计模式与范式 -结构型:4.适配器模式

概述 前面我们学习了代理模式、桥接模式、装饰器模式&#xff0c;本章再来学习一个比较常用的结构性模式&#xff1a;适配器模式。这个模式相对来说比较简单&#xff0c;应用场景也很具体。 关于适配器模式&#xff0c;有类适配器和对象适配器两种实现方式&#xff0c;以及常…

SQLServer数据库使用Function实现根据字段内容的拼音首字母进行数据查询

实现SQL首字母查询分两步&#xff0c;第一步建Function&#xff0c;第二步引用新建的Function。 1. 首先需要自定义一个查询的Function&#xff0c;详细SQL如下&#xff1a; ALTER function [dbo].[GetDataByPY](str nvarchar(4000)) returns nvarchar(4000) as begin decla…

【Java】MyBatis快速入门及详解

文章目录 1. MyBatis概述2. MyBatis快速入门2.1 创建项目2.2 添加依赖2.3 数据准备2.4 编写代码2.4.1 编写核心配置文件2.4.2 编写SQL映射文件2.4.3 编写Java代码 3. Mapper代理开发4. MyBatis核心配置文件5. 案例练习5.1 数据准备5.2 查询数据5.2.1 查询所有数据5.2.2 查询单条…