带头双向循环链表实现

本文介绍了如何在C语言中实现双向循环链表的基本操作,包括初始化、打印、头插、头删、尾插、尾删、查找、插入和删除节点。代码详细展示了每个函数的功能,便于理解和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 双向循环链表是由链表中的,循环链表与双向链表和有哨兵位共同构成

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int LTDataType;


typedef struct LTNode
{
	LTDataType data;
	struct LTNode* next;
	struct LTNode* prev;
}LTNode;
//初始化头结点
LTNode* LTInit();
//打印链表
void LTPrint(LTNode* head);
//链表尾插
void LTPushBack(LTNode* head, LTDataType x);
//链表尾删
void LTPopBack(LTNode* head);
//链表头插
void LTPushFront(LTNode* head,LTDataType x);
//链表头删
void LTPopFront(LTNode* head);
//链表查找
LTNode* LTFind(LTNode* head, LTDataType x);
//链表pos之前插入
void LTInsert(LTNode* pos, LTDataType x);
//链表pos之后插入
void LTErase(LTNode* pos);
//销毁双向链表
void LTDestroy(LTNode** head);
//打印双向链表
void LTPrint(LTNode* head);
LTNode* BuyLTNode(LTDataType x)
{
	LTNode* Node = NULL, * Head = NULL;
	Node = (LTNode*)malloc(sizeof(LTNode));
	if (Node == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	Head = Node;
	Head->data = x;
	Head->next = NULL;
	Head->prev = NULL;
}
//创建头结点
LTNode* LTInit()
{
	LTNode* head = BuyLTNode(-1);
	head->next=head;
	head->prev = head;
	return head;
}
//链表是否为空
bool LTEmpty(LTNode* head)
{
	assert(head);
	return head->next == head;
}
//打印链表
void LTPrint(LTNode* head)
{
	assert(head);
	assert(!LTEmpty(head));
	printf("Head -> ");
	LTNode* Node = head->next;
	while (Node != head)
	{
		printf("%d <-> ", Node->data);
		Node = Node->next;
	}
	printf("\n");
}


//尾插
void LTPushBack(LTNode* head,LTDataType x)
{
	assert(head);
	//双向带头循环头结点prev指向尾节点
	LTNode* Newhead = head;
	LTNode* Node=BuyLTNode(x);
	Node->prev = Newhead->prev;
	Node->prev->next = Node;
	Node->next = Newhead;
	Newhead->prev = Node;
}
//尾删
void LTPopBack(LTNode* head)
{
	assert(head);
	assert(!LTEmpty(head));
	LTNode* tail = NULL, * tailprev = NULL;
	//存储为节点的尾节点的信息
	tail = head->prev;
	//存储tail前一个节点的地址
	tailprev = tail->prev;
	//链接新尾节点
	head->prev = tailprev;
	tailprev->next = head;
	//释放尾节点
	free(tail);


}
//链表的头插
void LTPushFront(LTNode* head, LTDataType x)
{
	assert(head);
	LTNode* Node=NULL, * Newhead=NULL;
	Node = BuyLTNode(x);
	Newhead = head->next;
	Node->next = Newhead;
	Newhead->prev = Node;
	Node->prev = head;
	head->next = Node;
}
//链表的头删
void LTPopFront(LTNode* head)
{
	assert(head);
	assert(!LTEmpty(head));
	LTNode* Newhead = NULL, * Front = NULL;
	Front = head->next;
	Newhead = Front->next;
	Newhead->prev = head;
	head->next = Newhead;
	free(Front);
}
//链表查找
LTNode* LTFind(LTNode* head, LTDataType x)
{
	LTNode* Newhead = head->next;
	while (Newhead != head)
	{
		if (Newhead->data == x)
		{
			return Newhead;
		}
		Newhead = Newhead->next;
	}
	return NULL;
}
//pos前插入
void LTInsert(LTNode* pos, LTDataType x)
{
	assert(pos);
	LTNode* Node = BuyLTNode(x);
	LTNode* posprev = pos->prev;
	posprev->next = Node;
	Node->prev = posprev;
	Node->next = pos;
	pos->prev = Node;
}
//pos位置删除
void LTErase(LTNode* pos)
{
	assert(pos);
	//记录pos前后
	LTNode* pprev = pos->prev, * pnext = pos->next;
	pprev->next = pnext;
	pnext->prev = pprev;
	free(pos);
}
//销毁
void LTDestroy(LTNode** head)
{
	LTNode* cur =  ( * head)->next;
	while (cur!=*head)
	{
		//存储下一个节点
		LTNode* node = cur->next;
		//释放
		free(cur);
		//跳转到下个节点
		cur = node;
	}
	free(*head);
	*head = NULL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值