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

这篇具有很好参考价值的文章主要介绍了带头 + 双向 + 循环链表增删查改实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

源码:

List.c文件:

List.h文件:

简单的测试:



带头 + 双向 + 循环链表增删查改实现,数据结构,链表,数据结构

很简单,没什么好说的,直接上源码。文章来源地址https://www.toymoban.com/news/detail-818227.html

源码:

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

到了这里,关于带头 + 双向 + 循环链表增删查改实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】双向带头循环链表的实现

    前言:在前面我们学习了顺序表、单向链表,今天我们在单链表的基础上进一步来模拟实现一个带头双向链表。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:数据结构 👈 💯代码仓库:卫卫周大胖的学习日记💫 💪关注博主和博主一起学习!一起努力! 带头双向循环链

    2024年01月15日
    浏览(49)
  • 数据结构-带头双向循环链表的实现

    前言           带头双向循环链表是一种重要的数据结构,它的结构是很完美的,它弥补了单链表的许多不足,让我们一起来了解一下它是如何实现的吧!         它的节点中存储着数据和两个指针,一个 指针_prev 用来记录前一个节点的地址,另一个指针 _next 用来记录后一

    2024年02月13日
    浏览(49)
  • 【数据结构 -- C语言】 双向带头循环链表的实现

    目录 1、双向带头循环链表的介绍 2、双向带头循环链表的接口 3、接口实现 3.1 开辟结点 3.2 创建返回链表的头结点 3.3 判断链表是否为空 3.4 打印 3.5 双向链表查找 3.6 双向链表在pos的前面进行插入 3.6.1 头插 3.6.2 尾插 3.6.3 更新头插、尾插写法 3.7 双向链表删除pos位置的节点

    2024年02月09日
    浏览(64)
  • 【数据结构】—带头双向循环链表的实现(完美链表)

    链表结构一共有八种形式,在前面的文章里已经讲完了不带头单向非循环链表的实现,但是我们发现该链表实现尾插与尾删时比较麻烦,要先从头节点进行遍历,找到尾节点,时间复杂度为O(N),而本次所讲的带头双向循环单链表,则可以直接找到尾节点。 虽然该链表看起来

    2024年01月25日
    浏览(63)
  • 数据结构之双向带头循环链表函数功能实现与详细解析

    个人主页:点我进入主页 专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶 C语言刷题       数据结构初阶 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.前言 2.带头双向循环链表函数实现 3.总结         在前面我

    2024年02月05日
    浏览(54)
  • 【数据结构和算法】实现带头双向循环链表(最复杂的链表)

    前文,我们实现了认识了链表这一结构,并实现了无头单向非循环链表,接下来我们实现另一种常用的链表结构,带头双向循环链表。如有仍不了解单向链表的,请看这一篇文章(7条消息) 【数据结构和算法】认识线性表中的链表,并实现单向链表_小王学代码的博客-CSDN博客

    2024年01月17日
    浏览(78)
  • 【数据结构】双向链表的增删查改(C 代码实现)

    引入双向链表:关于单链表的问题与讨论 单链表存在的毛病: 因为单链表 只能单向 遍历链表, 对于 前插 这个操作,单链表必 须得找到所需前插节点位置的前一个 ,那么这时就得 从头指针重新遍历一次 链表,会造成时间复杂度大大增加。 没有头节点(哨兵位)无法删除

    2024年02月08日
    浏览(54)
  • 数据结构入门(C语言版)线性表带头双向循环链表接口实现

    在上一篇博客我们讲述了链表的概念和结构,还实现了无头单向非循环链表接口写法,那么这一章节,我们来实现另一种常用的链表组成结构——带头双向循环链表。 如果对前面的链表基本概念还是不了解,可以看作者的上一篇博客: 线性表中链表介绍及无头单向非循环链

    2023年04月12日
    浏览(47)
  • 数据结构:链表基础OJ练习+带头双向循环链表的实现

    目录 一.leetcode剑指 Offer II 027. 回文链表 1.问题描述 2.问题分析与求解 (1) 快慢指针法定位链表的中间节点 (2) 将链表后半部分进行反转 附:递归法反转链表 (3) 双指针法判断链表是否回文 二.带头双向循环链表的实现 1.头文件 2.节点内存申请接口和链表初始化接口 3.链表的打

    2024年02月02日
    浏览(51)
  • 链接未来:深入理解链表数据结构(二.c语言实现带头双向循环链表)

    上篇文章简述讲解了链表的基本概念并且实现了无头单向不循环链表:链接未来:深入理解链表数据结构(一.c语言实现无头单向非循环链表)-CSDN博客 那今天接着给大家带来带头双向循环链表的实现 : 头文件DoubleList.h:用来基础准备(常量定义,typedef),链表表的基本框架

    2024年01月16日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包