队列 -- 双向循环链表实现

 代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

/*
	队列--双向循环链表实现
		通过对线性表的插入删除操作在异端完成
		比如:
			头插入对应的是尾删除
			尾插入对应的是头删除
		出数据的一端是队头,进数据的是队尾
	栈:	  先进后出
	队列: 先进先出
*/

// 创建双向循环链表节点
struct Node
{
	int a;
	struct Node* pPre;
	struct Node* pNext;
};
// 1.创建队列的空头
struct Node* Queue();
// 2.判断队列是否为空
bool isEmpty(struct Node* pQueue);
// 3.获取队头 -- 出数据的一端
struct Node* Front(struct Node* pQueue);
// 4.获取队尾 -- 进数据的一端
struct Node* Back(struct Node* pQueue);
// 5.入队
void Push(struct Node* pQueue, int a);
// 6.出队
void PopEnd(struct Node* pQueue);
// 7.释放队列
void Free(struct Node** pQueue);


int main()
{
	// 创建队列空头
	struct Node* pHead = Queue();
	// 判断队列是否为空
	bool ret = isEmpty(pHead);	// true
	int arr[5] = { 1,2,3,4,5 };
	// 入队
	for (int i = 0; i < 5; i++)
	{
		Push(pHead, arr[i]);	// 5 4 3 2 1 【头添加】
	}
	// 获取队头
	for (int i = 0; i < 5; i++)
	{
		// 获取队头
		arr[i] = Front(pHead)->a;
		printf("%d\t", arr[i]);	 // 5 4 3 2 1 
		// 出队
		PopEnd(pHead);
	}
	
	system("pause");
	return 0;
}

// 1.创建队列的空头
struct Node* Queue()
{
	// 创建节点,动态申请内存空间
	struct Node* pt = (struct Node*)malloc(sizeof(struct Node));
	// 判空
	if (NULL == pt)
	{
		return NULL;
	}
	// 给节点成员赋值
	pt->a = -1;
	// 注意这里前后指针要指向自身,形成一个环
	pt->pNext = pt;
	pt->pPre = pt;
	return pt;
}
// 2.判断队列是否为空
bool isEmpty(struct Node* pQueue)
{
	if (NULL == pQueue || pQueue == pQueue->pNext)
	{
		return true;
	}
	return false;
}
// 3.获取队头 -- 出数据的一端  获取尾节点
//【这里用:头添加 尾删除,出数据的一端是队头,进数据的一端是队尾】
struct Node* Front(struct Node* pQueue)
{
	// 判断链表是否为空
	if (NULL == pQueue || pQueue->pNext == pQueue)
	{
		return NULL;
	}
	// 返回尾节点
	return pQueue->pPre;
}
// 4.获取队尾 -- 进数据的一端 获取头节点(空头的下一个节点)
struct Node* Back(struct Node* pQueue)
{
	// 判断队列是否为空
	if (NULL == pQueue || pQueue->pNext == pQueue)
	{
		return NULL;
	}
	// 返回空头的下一个节点 队列第二个节点
	return pQueue->pNext;
}
// 5.入队
void Push(struct Node* pQueue, int a)
{
	// 检验参数合法性
	if(NULL == pQueue)
	{
		return;
	}
	// 进行头添加
	// 创建要插入的节点
	struct Node* pt = (struct Node*)malloc(sizeof(struct Node));
	// 判空
	if (NULL == pt)
	{
		return;
	}
	// 给节点赋值
	pt->a = a;
	pt->pNext = NULL;
	pt->pPre = NULL;
	// 将节点插入到头
	// 先连
	pt->pPre = pQueue->pPre;
	pt->pNext = pQueue;
	// 后断
	pQueue->pPre->pNext = pt;
	pQueue->pPre = pt;
}
// 6.出队 -- 尾删除
void PopEnd(struct Node* pQueue)
{
	// 检验参数合法性
	if (NULL == pQueue)
	{
		return;
	}
	// 记录要删除的尾节点
	struct Node* pt = pQueue->pPre;
	// 抠出尾
	pt->pPre->pNext = pQueue;
	pQueue->pPre = pt->pPre;
	// 释放记录的尾节点
	free(pt);
}
// 7.释放队列
void Free(struct Node** pQueue)
{
	// 检验参数合法性
	if (NULL == *pQueue)
	{
		return;
	}
	// 记录空头
	struct Node* pt = *pQueue;
	do
	{
		// 记录要释放的pt
		struct Node* pTemp = pt;
		// 抠出pt
		pt = pt->pNext;
		// 释放抠出的pt
		free(pTemp);
		// 将记录的pt 置空
		pTemp = NULL;
	} while (pt != *pQueue);
	// 将空队头置空
	*pQueue = NULL;
}

程序运行结果:

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值