/*************************************************
*
* file name:DoubleLinkQueue.c
* author :[email protected]
* date :2024/04/28
* brief :构建双向循环链队的接口
* note :None
*
* CopyRight (c) 2024 [email protected] All Right Reseverd
*
**************************************************/
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
/*************************************************
*
* func name :
* brief :
* func parameter:
*
*
* return :None
* note :None
* func author :[email protected]
* date :2024/04/28
* version :V1.0
**************************************************/
// 构建链队的结点(队数据域+指针域1+指针域2)
typedef int DataType_t;
typedef struct LinkQueue
{
DataType_t Data;
struct LinkQueue *Prev;
struct LinkQueue *Next;
} LinkQueue_t;
// 创建一个空的顺序循环队列,并对其进行初始化
LinkQueue_t *LinkQueue_Creat(void)
{
// 为循环队列的头结点申请内存空间
LinkQueue_t *Head = (LinkQueue_t *)calloc(1, sizeof(LinkQueue_t));
if (NULL == Head)
{
perror("calloc memory for Head is failed!\n");
exit(-1);
}
Head->Next = Head;
Head->Prev = Head;
return Head;
}
// 创建新结点,并对其进行初始化
LinkQueue_t *LinkQueue_NewNode(DataType_t data)
{
// 为循环队列的头结点申请内存空间
LinkQueue_t *NewNode = (LinkQueue_t *)calloc(1, sizeof(DataType_t));
if (NULL == NewNode)
{
perror("calloc memory for NewNode is failed!\n");
return NewNode;
}
NewNode->Data = data; // 初始化数据域
NewNode->Prev = NewNode; // 初始化指针域1
NewNode->Next = NewNode; // 初始化指针域2
return NewNode;
}
// 判断队列是否为空
bool LinkQueue_IsEmpty(LinkQueue_t *Head)
{
return (Head->Next == Head) ? true : false;
}
// 入队操作(尾插)
bool LinkQueue_Enqueue(LinkQueue_t *Head, DataType_t data)
{
LinkQueue_t *Phead = Head->Next;
LinkQueue_t *NewNode = LinkQueue_NewNode(data);
if (LinkQueue_IsEmpty(Head)) // 判断链表是否为空
{
// 链表为空
Head->Next = NewNode; // 让头结点的Next指针指向新结点
NewNode->Next = NewNode; // 让新结点的Next指针指向新结点
NewNode->Prev = NewNode; // 让新结点的Prev指针指向新结点
return true;
}
// 2.2链表非空
NewNode->Prev = Phead->Prev; // 新节点的Prev指针指向尾结点
NewNode->Next = Phead; // 新结点的Next指针指向首结点
Phead->Prev->Next = NewNode; // 尾结点的Next指针指向新结点
Phead->Prev = NewNode; // 首结点的Prev指针指向新结点
return true;
}
// 出队操作(头删)
DataType_t LinkQueue_Dequeue(LinkQueue_t *Head)
{
// 判断链表是否为空
if (LinkQueue_IsEmpty(Head))
{
printf("Link queue is empty!\n");
return false; // 为空则删除失败
}
DataType_t temp = Head->Next->Data;
LinkQueue_t *Phead = Head->Next; // 备份首节点地址,用于最后释放首结点地址
Phead->Prev->Next = Phead->Next; // 让尾结点的Next指针指向首节点的直接后继结点
Phead->Next->Prev = Phead->Prev; // 让首结点的直接后继结点的Prev指针指向尾结点
Head->Next = Phead->Next; // 让头结点的Next指针指向首结点的直接后继结点
Phead->Next = NULL; // 让首结点的Next指针指向NULL
Phead->Prev = NULL; // 让首结点的Prev指针指向NULL
free(Phead);
return temp;
}
bool LinkQueue_Print(LinkQueue_t *Head)
{
LinkQueue_t *Front = Head->Next; // 备份头结点
while (Front->Next != Head->Next)
{
printf("%d ", Front->Data); // 打印链表
Front = Front->Next; // 遍历链表
}
printf("%d ", Front->Data);
printf("\n");
return true;
}
int main(void)
{
LinkQueue_t *Head = LinkQueue_Creat();
LinkQueue_Enqueue(Head, 1);
LinkQueue_Enqueue(Head, 2);
LinkQueue_Enqueue(Head, 3);
LinkQueue_Print(Head);
printf("The dequeue element is %d\n", LinkQueue_Dequeue(Head));
LinkQueue_Print(Head);
return 0;
}
标签:Head,队列,LinkQueue,结点,接口,Next,链表,NewNode,Prev
From: https://www.cnblogs.com/bell-c/p/18164756