数据结构-带头双向循环链表的基本实现(C语言,简单易懂,含全部代码)

2023-11-19

链表的概念和结构

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

结构:实际中链表的结构非常多样,以下情况组合起来就有8种链表结构。

(1)单向、双向
(2)带头、不带头
(3)循环、非循环

本篇主要详解带头双向循环链表,结构如图:
在这里插入图片描述

带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。

链表的实现

首先在头文件中定义结构体和提供接口:

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

typedef int LTDataType;

typedef struct ListNode
{
	struct ListNode* next;
	struct ListNode* prev;
	LTDataType data;
	
}ListNode;

void ListPrint(ListNode* phead);//打印链表

ListNode* BuyListNode(LTDataType x);//开辟新节点

ListNode* ListInit();//初始化哨兵位

void ListPushBack(ListNode* phead, LTDataType x);//尾插,只要不改变头指针的内容,就不用传二级指针

void ListPushFront(ListNode* phead, LTDataType x);//头插

void ListPopBack(ListNode* phead);//尾删

void ListPopFront(ListNode* phead);//头删

ListNode* ListFind(ListNode* phead, LTDataType x);//查找

void ListInsert(ListNode* pos, LTDataType x);//pos位置前插

void ListErase(ListNode* pos);//pos位置删除

其次在源文件中实现接口功能:
(1)链表打印

void ListPrint(ListNode* phead)
{
	ListNode* cur = phead;
	while (cur != phead)
	{
		printf("%d", cur->data);
		cur = cur->next;//找到下一个节点
	}
	printf("\n");
}

(2)开辟新节点

ListNode* BuyListNode(LTDataType x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	node->next = NULL;
	node->prev = NULL;
	node->data = x;
	return node;
}

(3)初始化哨兵位

ListNode* ListInit()
{
	ListNode* phead = BuyListNode(0);
	phead->next = phead;
	phead->prev = phead;

	return phead;
}

(4)尾插
带头双向循环链表的头插尾插非常方便,只需要找到头(phaed->next)和尾(phead->prev)并链接

void ListPushBack(ListNode* phead, LTDataType x)
{
	//无论是0个(只有哨兵位)还是多个节点都可以,与节点个数无关
	assert(phead);
	ListNode* tail = phead->prev;//找尾
	ListNode* newnode = BuyListNode(x);

	tail->next = newnode;
	newnode->prev = tail;
	newnode->next = phead;
	phead->prev = newnode;
}

在这里插入图片描述
(5)头插

void ListPushFront(ListNode* phead, LTDataType x)
{
	assert(phead);
	ListNode* first = phead->next;
	ListNode* newnode = BuyListNode(x);
	//phead newnode first 
	phead->next = newnode;
	newnode->prev = phead;
	newnode->next = first;
	first->prev = newnode;
}

在这里插入图片描述
(6)尾删

void ListPopBack(ListNode* phead)
{
	assert(phead);
	assert(phead->next != phead);
	ListNode* tail = phead->prev;
	ListNode* tailPrev = tail->prev;
	free(tail);

	tailPrev->next = phead;
	phead->prev = tailPrev;
}

(7)头删

void ListPopFront(ListNode* phead)
{
	assert(phead);//没有节点
	assert(phead->next != phead);//只有phead

	ListNode* first = phead->next;
	ListNode* second = first->next;
	
	free(first);

	phead->next = second;
	second->prev = phead;
}

(8)查找x

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;
}

(9)pos位置前插

void ListInsert(ListNode* pos, LTDataType x)
{
	assert(pos);

	ListNode* prev = pos->prev;
	ListNode* newnode = BuyListNode(x);
	prev->next = newnode;
	newnode->prev = prev;
	newnode->next = pos;
	pos->prev = newnode;
}

(10)pos位置删除

void ListErase(ListNode* pos)
{
	assert(pos);

	ListNode* prev = pos->prev;
	ListNode* next = pos->next;

	prev->next = next;
	next->prev = prev;

	free(pos);
}

主函数的设计大家可以自由发挥,做个简单的测试功能调用函数或是创建菜单栏实现交互都可以。我水平有限,请朋友们谅解!写的不好的地方还请大佬们指出。最后,如果这篇文章对你有帮助,就点个赞或者收藏评论一下吧,谢谢大家支持

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构-带头双向循环链表的基本实现(C语言,简单易懂,含全部代码) 的相关文章

随机推荐

  • Java多线程(四):什么是死锁以及如何解决死锁

    目录 1 什么是死锁 2 死锁产生的原因 3 如何解决死锁问题 3 1 改变环路等待条件 3 2 破坏请求并持有条件 1 什么是死锁 死锁 是指两个或两个以上的进程在执行过程中 由于竞争资源或者由于彼此通信而造成的一种阻塞的现象 若无外力作
  • 【微信小程序】定时器超时处理设置方法【setInterval()和setTimeout()】

    2020年2月13日 0次阅读 共550个字 0条评论 0人点赞 QueenDekimZ Set Timeout Solution setTimeout和setInterval 函数都属于定时任务 一 settimeout延迟一段时间执行函
  • css中float用法

    float浮动 指将指定元素悬浮于所在整体之上 即将垂直排列的元素转换为水平同行显示 平时写出的HTML是具有先后顺序的 对于这个顺序我们称之为标准流 而浮动则是脱离标准流的另一个独立标准 下面给出float定义 float left 左浮
  • 阿里云大佬告诉你为什么学不会设计模式,归根到底还是方法不对

    最近总有读者在后台跟我说 工作几年 自己的代码质量似乎没有什么提升 我觉得他的情况非常典型 很多人应该或多或少都有过类似的经历 毕业几年 几乎一直在做复制黏贴的工作 偶尔会遇到原有业务扩展的需求 想简单应付一下完事的话 也不难 无非就是多加
  • 查询水果价格 (15分)

    给定四种水果 分别是苹果 apple 梨 pear 桔子 orange 葡萄 grape 单价分别对应为3 00元 公斤 2 50元 公斤 4 10元 公斤 10 20元 公斤 首先在屏幕上显示以下菜单 1 apple 2 pear 3 o
  • Hadoop学习——MapReduce的简单介绍及执行步骤

    MapReduce概述 MapReduce是一个分布式的计算框架 编程模型 最初由由谷歌的工程师开发 基于GFS的分布式计算框架 后来Cutting根据 Google Mapreduce 设计了基于HDFS的Mapreduce分布式计算框架
  • IDEA修改内存未生效原因和解决

    修改IDEA安装目录下的idea64 exe vmoptions server Xms1024m Xmx2048m XX ReservedCodeCacheSize 2048m 发现IDEA的内存修改并未生效 右下角显示依然是974M 原因
  • windows下进程间通信的(13种方法)

    Windows进程间的通信 迎风的祺 博客园 windows下进程间通信的 13种方法 phymat nico的专栏 CSDN博客 windows进程间通信
  • eclipse报错 parameterized types are only available if source level is 1.5 or greater

    preface 好久没有更新 blog 了 最近在 写新的项目 今天在用eclipse 出现了之前遇到的问题 这里记录下 问题 eclipse 控制台 报错 parameterized types are only available if
  • CUDA+OPENCV+PYTHON tensorflow 源码环境搭建

    CUDA OPENCV PYTHON tensorflow 源码环境搭建 接上文caffe环境安装 https blog csdn net u012350025 article details 104589982 主机环境ubuntu18
  • 基于C++的带权无向图的实现 (五)- 连通图和连通分量

    该系列文章是本人整理的有关带权无向图的数据结构和算法的分析与实现 若要查看源码可以访问我的github仓库 如有问题或者建议欢迎各位指出 目录 基于C 的带权无向图的实现 一 数据结构 基于C 的带权无向图的实现 二 遍历算法 基于C 的带
  • 台式计算机怎么看有没有开独显,台式机独立显卡怎么样打开

    给台式机插入了独立显卡 但不会打开怎么办呢 下面由学习啦小编给你做出详细的台式机独立显卡打开方法介绍 希望对你有帮助 台式机独立显卡打开方法一 把显示器的数据连接线接到独立显卡上 用的就是独立显卡 把显示器的数据线连接在主板的显示输出口上
  • MyEclipse8.5的安装过程

    1 双击进行安装 点Next接受 选择好路径后 等待安装完毕 2 选择路径 3 进入工作台如下图 4 配置Tomcat 工具栏 Window Preferences 5 Myeclipse Servers Tomcat 选择版本 勾选Ena
  • 2029:【例4.15】水仙花数

    2029 例4 15 水仙花数 时间限制 1000 ms 内存限制 65536 KB 提交数 1247 通过数 720 题目描述 求100 999中的水仙花数 若三位数ABC ABC A3 B3 C3 则称ABC为水仙花数 例如153 13
  • springboot2.x默认采用cglib代理,以及配置jdk动态代理的方法

    众所周知 springboot开启AOP需要在启动类加上注解 EnableAspectJAutoProxy 但开发过程中发现即使不加 EnableAspectJAutoProxy 注解 bean还是被代理过 而且是Cglib代理对象 此时在
  • win32下Qt5BLE蓝牙开发笔记

    BLE简介 BLE蓝牙是蓝牙2 0以上的蓝牙模块 经典蓝牙是蓝牙2 0以下的蓝牙 蓝牙分为客户端和服务器两端 经典蓝牙可以通过socket编程进行客户端与服务器之间的通信 与网络socket相似 BLE蓝牙则无法使用这种方式进行通信 BLE
  • ICASSP 2023说话人识别方向论文合集

    今年入选 ICASSP 2023 的论文中 说话人识别 声纹识别 方向约有64篇 初步划分为Speaker Verification 31篇 Speaker Recognition 9篇 Speaker Diarization 17篇 An
  • 算法竞赛当中的思考方法——方法论篇。

    方法论 万物皆朴素的第一性原理 几乎任何领域的任何问题的解决方案 都可以看作是 某个结构上的朴素方法的优化 计算机只能处理规模有限的问题 在给定规模且不考虑效率的情况下 问题一定存在朴素解法 具体手段有直接模拟 利用bit枚举 各种搜索算法
  • Spring Cloud面试8连问,谁顶得住?

    问题一 什么是 Spring Cloud Spring cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序 提供与外部系统的集成 Spring cloud Task 一个生命周期短暂的微服务框架 用于
  • 数据结构-带头双向循环链表的基本实现(C语言,简单易懂,含全部代码)

    链表的概念和结构 概念 链表是一种物理存储结构上非连续 非顺序的存储结构 数据元素的逻辑顺序是通过链表中的指针链接次序实现的 结构 实际中链表的结构非常多样 以下情况组合起来就有8种链表结构 1 单向 双向 2 带头 不带头 3 循环 非循