带头 + 双向 + 循环链表增删查改实现

news2024/9/22 20:00:26

目录

源码:

List.c文件:

List.h文件:

简单的测试:



很简单,没什么好说的,直接上源码。

源码:

List.c文件:

#include"DLList.h"

ListNode* creadNode(LTDataType x)
{
	ListNode* temp = (ListNode*)malloc(sizeof(ListNode));
	if (temp == NULL)
	{
		perror("malloc fail !\n");
		return -1;
	}
	temp->data = x;
	temp->next = NULL;
	temp->prev = NULL;
	return  temp;

}

// 创建返回链表的头结点.
ListNode* ListCreate()
{
	ListNode* temp = (ListNode*)malloc(sizeof(ListNode));
	if (temp == NULL)
	{
		perror("malloc fail !\n");
		return -1;
	}
	temp->next = temp;
	temp->prev = temp;
	temp->data = 0;
	return  temp;
}
// 双向链表销毁
void ListDestory(ListNode* pHead)
{
	//头节点一定不会为空
	assert(pHead);
	if (pHead->next == pHead)
	{
		free(pHead);
		pHead = NULL;
	}
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
		ListNode* next = cur->next;
		free(cur);
		cur = next;
	}
	printf("销毁成功!");
}
// 双向链表打印
void ListPrint(ListNode* pHead)
{
	assert(pHead);
	if (pHead->next == pHead)
	{
		printf("List is NULL!\n");
		exit(-1);
	}
	printf("哨兵位<=>");
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
		printf("%d<=>",cur->data);
		cur = cur->next;
	}
	printf("\n");
}

// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x)
{
	ListNode* newNode = creadNode(x);
	ListNode* tail = pHead->next;
	while (tail->next != pHead)
	{
		tail = tail->next;
	}
	newNode->next = pHead;
	pHead->prev = newNode;
	tail->next = newNode;
	newNode->prev = tail;
}

// 双向链表尾删
void ListPopBack(ListNode* pHead)
{
	assert(pHead);
	if (pHead->next == pHead)
	{
		printf("List is NULL!\n");
		exit(-1);
	}
	ListNode* tail = pHead->prev;
	ListNode* prev = tail->prev;
	pHead->prev = prev;
	prev->next = pHead;
	free(tail);
	
}
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x)
{
	ListNode* newNode = creadNode(x);
	newNode->next = pHead->next;
	pHead->prev = newNode;
	pHead->next = newNode;
	newNode->prev = pHead;
}
// 双向链表头删
void ListPopFront(ListNode* pHead)
{
	assert(pHead);
	if (pHead->next == pHead)
	{
		printf("List is  NULL!\n");
		exit(-1);
	}
	ListNode* firstNode = pHead->next;
	ListNode* secondNode = firstNode->next;
	pHead->next = secondNode;
	secondNode->prev = pHead;
	free(firstNode);
	firstNode = NULL;
}
// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
// 双向链表在pos的前面进行插入
void ListInsert(ListNode *pHead, ListNode* pos, LTDataType x)
{
	assert(pos);
	if (pos == pHead)
	{
		ListPushBack(pHead,x);
	}
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
		if (cur->data == pos->data)
		{
			ListNode* prev = pos->prev;
			ListNode *newNode  = creadNode(x);
			prev->next = newNode;
			newNode->prev = prev;
			newNode->next = pos;
			pos->prev = newNode;
			return;
		}
		cur = cur->next;
	}
}
// 双向链表删除pos位置的节点
void ListErase(ListNode* pHead,ListNode* pos)
{
	assert(pHead);
	if (pos == pHead->next)
	{
		ListPopFront(pHead);
	}
	if (pos == pHead->prev)
	{
		ListPopBack(pHead);
	}
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
		if (cur->data == pos->data)
		{
			ListNode* prev = cur->prev;
			ListNode* next = cur->next;
			prev->next = next;
			next->prev = prev;
			free(cur);
			return;
		}
		cur = cur->next;
	}
}

List.h文件:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

// 带头 + 双向 + 循环链表增删查改实现
typedef int LTDataType;
typedef struct ListNode
{
	LTDataType data;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;

ListNode* creadNode();
// 创建返回链表的头结点.
ListNode* ListCreate();
// 双向链表销毁
void ListDestory(ListNode* pHead);
// 双向链表打印
void ListPrint(ListNode* pHead);
// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* pHead);
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* pHead);
// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pHead,ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pHead,ListNode* pos);

简单的测试:

#include"DLList.h"

void test1(ListNode * head) {
	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListPopBack(head);
	ListPrint(head);

	ListPopBack(head);
	ListPrint(head);

	ListPopBack(head);
	ListPrint(head);

	ListPopBack(head);
	ListPrint(head);

	ListPopBack(head);
	ListPrint(head);

	ListPopBack(head);
	ListPrint(head);

}

void test2(ListNode* head) {
	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListPopFront(head);
	ListPrint(head);
}


void test3(ListNode* head) {
	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListFind(head,2);
	ListFind(head,7);
	ListPrint(head);
}

void test4(ListNode* head) {
	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListInsert(head, ListFind(head, 2),10);
	ListInsert(head, ListFind(head, 1),10);
	ListInsert(head, ListFind(head, 5),10);
	ListInsert(head, ListFind(head, 6),10);
	ListPrint(head);
}

void test5(ListNode* head) {
	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);
	ListErase(head,ListFind(head,5));
	ListErase(head,ListFind(head,1));
	ListErase(head,ListFind(head,2));
	ListPrint(head);
}


int main()
{
	ListNode* head = ListCreate();
	//test1(head);
	//test2(head);
	//test3(head);
	//test4(head);
	test5(head);

	ListDestory(head);

	return 0;
}

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

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

相关文章

自己重装Win10系统详细步骤教程

用户不喜欢自己电脑当前的操作系统&#xff0c;想自己重新一款喜欢的Win10系统&#xff0c;但不知道如何操作才能重新安装系统Win10&#xff1f;以下小编带来自己重装Win10系统详细步骤教程&#xff0c;帮助用户们轻轻松松地完成Win10系统的重装&#xff0c;快速体验Win10系统的…

2023.1.21 关于 Redis 主从复制详解

目录 引言 单点问题 分布式系统 主从模式 配置 Redis 主从结构 断开主从关系 切换主从关系 补充知识点一 只读 网络延迟 拓扑结构 一主一从 一主多从 树形主从结构 主从复制的基本流程 数据同步 replicationid offset pzync 运行流程 具体流程 补充知识点二…

JS 将字符串‘10.3%‘ 经过运算加2转换为 ‘12.3%‘

文章目录 需求分析 需求 已知 字符串 a ‘10.3%’&#xff0c;现需将转换为 字符串’12.3%’ 分析 去掉百分号&#xff0c;将字符串转换为数字 const aNumber parseFloat(10.3%); const resultNumber aNumber 2;将结果转换为带百分号的字符串 const resultString re…

〖大前端 - ES6篇①〗- ES6简介

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

2024年Java SpringBoot 计算机软件毕业设计题目推荐

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作✌ 主要内容&#xff1a;SpringBoot、Vue、SSM、HLM…

k8s---pod的水平自动伸缩HPA

HPA&#xff1a;Horizontal Pod Autoscaling是pod的水平自动伸缩。是k8s自带的模块 pod占用CPU的比率到达一定的阈值会触发伸缩机制。 replication controller&#xff1a;副本控制器。控制pod的副本数 deployment controller&#xff1a;节点控制器。部署pod hpa控制副本的…

浅析位运算符(左移、右移、与、或、异或)

C语言是一种很奇妙的语言&#xff0c;它既有高级语言的特点&#xff0c;又有低级语言的特点&#xff0c;支持位运算让它更方便于硬件编程。 一、左移运算符&#xff08;<<&#xff09; 左移运算就是将一个二进制位的操作数按指定位数整体向左移位&#xff0c;移出位被丢…

【力扣】记录一下竞赛分上 Knight

记录一下力扣上 Knight 力扣的题还是相对来说比较简单的&#xff0c;前两个月写的题多一点&#xff0c;后面几乎都是只做了每日一题&#xff0c;感觉正常来说刷个两三个月的题水平就差不多够了&#xff0c;甚至在我才刷半个月的时候就可以做三题了&#xff0c;排名和现在差不多…

手机上菜谱记录簿在哪 用备忘录放大看菜谱更清晰

作为一个热爱生活的现代人&#xff0c;我深知健康饮食的重要性。然而&#xff0c;每当我想亲手为自己和家人烹饪美食时&#xff0c;厨艺的不精常常让我望而却步。好在互联网时代&#xff0c;网上搜罗的各式菜谱成了我的救星。但问题是&#xff0c;每次做菜时都得反复查找&#…

docker运行redis,jdk,nginx

Redis 1.查询redis [rootlocalhost ~]# docker search redis NAME DESCRIPTION STARS OFFICIAL redis Redis is an open source key-value store that… 12620 …

解决vue 2.6通过花生壳ddsn(内网穿透)实时开发报错Invalid Host header和websocket

请先核对自己的vue版本&#xff0c;我的是2.6.14&#xff0c;其他版本未测试 起因 这两天在维护一个基于高德显示多个目标&#xff08;门店&#xff09;位置的项目&#xff0c;由于高德要求定位必须使用https服务&#xff0c;遂在本地无法获取到定位坐标信息&#xff0c;于是…

因谷歌Play Store审核超过7天和联系他们的方式

三种联系他们的方式 1.让他们打电话过来 英语好不好没关系&#xff0c;主要是他们讲着一口浓厚的印度口音英语&#xff0c;很难听懂 2.在线实时聊天沟通 可以选择英文、中文、但是英文肯定容易约上 3.发送邮件 回复太慢了&#xff0c;1-2天回复你一次 传送门&#xff1…

时间轮设计

目录 基本概念 函数定义 函数实现与测试 测试1结果如下 测试2结果如下 基本概念 时间轮 是一种 实现延迟功能&#xff08;定时器&#xff09; 的 巧妙算法。如果一个系统存在大量的任务调度&#xff0c;时间轮可以高效的利用线程资源来进行批量化调度。把大批量的调度任务…

【算法与数据结构】377、LeetCode组合总和 Ⅳ

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题明面上说是组合&#xff0c;实际上指的是排列。动态规划排列组合背包问题需要考虑遍历顺序。 d p …

[Python] opencv - 如何使用VideoCapture类进行摄像头视频捕获并显示

VideoCapture类介绍 OpenCV-Python 中的 VideoCapture 类是一个用于捕获视频的类&#xff0c;它可以从摄像头、视频文件或者设备上捕获视频。主要方法有&#xff1a; class VideoCapture:# Functions_typing.overloaddef __init__(self) -> None: ..._typing.overloaddef _…

性能篇:解密Stream,提升集合遍历效率的秘诀!

大家好&#xff0c;我是小米&#xff0c;一个热爱技术分享的小伙伴。今天我们来聊一聊 Java 中的 Stream&#xff0c;以及如何通过 Stream 来提高遍历集合的效率。 什么是Stream&#xff1f; 在开始深入讨论之前&#xff0c;我们先来了解一下什么是 Stream。 Stream 是 Java…

2024-01-19(SpringCloudThreadLocal)

1.Seata的TC服务注册到Nacos注册中心当中 2.Seata为我们提供了AT&#xff0c;TCC&#xff0c;SAGA&#xff0c;XA事务解决方案。 3.XA规范是一种分布式事务处理标准&#xff0c;XA规范描述了全局的TM与局部的RM之间的接口&#xff0c;几乎所有的主流的数据库都对XA规范提供了…

JavaScript递归函数如何匹配上下级id和pid的数据(for...of,foreach.reduce)

目录 一、for...of 二、forEach 三、reduce 递归函数是一种在编程中常用的方法&#xff0c;用于解决一些需要重复操作的问题。在JavaScript中&#xff0c;递归函数可以用来匹配上下级id和pid的数据结构&#xff0c;例如树形结构或者父子关系的数据。 一、for...of 首先…

【网络安全 -> 防御与保护】专栏文章索引

为了方便 快速定位 和 便于文章间的相互引用等 作为一个快速准确的导航工具 网络安全——防御与保护 &#xff08;一&#xff09;.信息安全概述

《移动通信原理与应用》——QAM调制解调仿真

目录 一、QAM调制与解调仿真流程图&#xff1a; 二、仿真结果&#xff1a; 三、Matlab仿真程序代码如下&#xff1a; 一、QAM调制与解调仿真流程图&#xff1a; QAM调制仿真流程图&#xff1a; QAM解调仿真流程图&#xff1a; 二、仿真结果&#xff1a; &#xff08;1&…