/********************************************************************************************************
*
*
* 該程式實現迴圈佇列元素的增刪改查,目的是提高設計程式的邏輯思維,另外為了提高可移植性,所以迴圈佇列中元素
* 的資料型別為DataType_t,使用者可以根據實際情況修改迴圈佇列中元素的型別。
*
* 另外,為了方便管理迴圈佇列,所以使用者設計SeqList_t結構體,該結構體中包含三個成員:地址+容量+有效元素的下標
*
*
*
* Copyright (c) 2023-2024 cececlmx@126.com All right Reserved
* ******************************************************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
// 指的是迴圈佇列中的元素的資料型別,使用者可以根據需要進行修改
typedef int DataType_t;
// 構造記錄迴圈佇列CircularQueue各項引數(迴圈佇列的首地址 + 迴圈佇列的容量 + 迴圈佇列隊尾下標+隊首下標)的結構體
typedef struct CircularQueue
{
DataType_t *Addr; // 記錄迴圈佇列首地址
unsigned int Size; // 記錄迴圈佇列的容量
int Rear; // 迴圈佇列隊尾下標
int Front; // 迴圈佇列隊首下標
} CirQueue_t;
// 建立迴圈佇列並對迴圈佇列進行初始化
CirQueue_t *CirQueue_Create(unsigned int size)
{
// 1.利用calloc為迴圈佇列的管理結構體申請一塊堆記憶體
CirQueue_t *Manager = (CirQueue_t *)calloc(1, sizeof(CirQueue_t));
if (NULL == Manager)
{
perror("calloc memory for manager is failed");
exit(-1); // 程式異常終止
}
// 2.利用calloc為所有元素申請堆記憶體
Manager->Addr = (DataType_t *)calloc(size, sizeof(DataType_t));
if (NULL == Manager->Addr)
{
perror("calloc memory for element is failed");
free(Manager);
exit(-1); // 程式異常終止
}
// 3.對管理迴圈佇列的結構體進行初始化(迴圈佇列容量 + 隊尾下標+隊首下標)
Manager->Size = size; // 對迴圈佇列中的容量進行初始化
Manager->Rear = 0; // 隊尾下標初值為0
Manager->Front = 0; // 隊首下標初值為0
return Manager;
}
// 判斷迴圈佇列是否已滿
bool CirQueue_IsFull(CirQueue_t *Manager)
{
return ((Manager->Rear + 1) % Manager->Size == Manager->Front) ? true : false;
}
// 入隊
bool CirQueue_Enqueue(CirQueue_t *Manager, DataType_t Data)
{
// 1.判斷迴圈佇列是否已滿
if (CirQueue_IsFull(Manager))
{
printf("CirQueue is Full!\n");
return false;
}
//if(Manager->Front == Manager->Rear&&Manager->Front!=0)
// 2.如果迴圈佇列有空閒空間,則把新元素新增到迴圈佇列尾部
Manager->Addr[Manager->Rear] = Data;
// 防止隊尾下標越界
Manager->Rear = (Manager->Rear + 1) % Manager->Size;
return true;
}
// 判斷迴圈佇列是否為空
bool CirQueue_IsEmpty(CirQueue_t *Manager)
{
return (Manager->Front == Manager->Rear) ? true : false;
}
// 出隊
DataType_t CirQueue_Dequeue(CirQueue_t *Manager)
{
DataType_t temp = 0;
// 1.判斷迴圈佇列是否為空
if (CirQueue_IsEmpty(Manager))
{
printf("CirQueue is Empty!\n");
return false;
}
// 2.把元素從隊首出隊,並備份到變數temp,並清空其值
temp = Manager->Addr[Manager->Front];
Manager->Addr[Manager->Front] = 0;
// 防止隊首下標越界
Manager->Front = (Manager->Front + 1) % Manager->Size;
return temp;
}
// 遍歷順序迴圈佇列的元素
void CirQueue_Print(CirQueue_t *Manager)
{
int pos = (Manager->Rear-Manager->Front+Manager->Size)%(Manager->Size);
for (int i=0;i<pos;i++)
{
printf("data=%d\n", Manager->Addr[(Manager->Front+i)%(Manager->Size)]);
}
}
int main(int argc, char const *argv[])
{
// 1.建立順序迴圈佇列
CirQueue_t *Manager = CirQueue_Create(7);
// 2.向順序迴圈佇列中插入新元素
printf("*********************************入隊********************************\n");
CirQueue_Enqueue(Manager, 5);
CirQueue_Enqueue(Manager, 2);
CirQueue_Enqueue(Manager, 1);
CirQueue_Enqueue(Manager, 4);
CirQueue_Enqueue(Manager, 6);
// //3.遍歷順序迴圈佇列
CirQueue_Print(Manager); // -- 5 2 1 4 6
printf("\n");
// 4.向順序迴圈佇列中插入新元素
printf("*********************************出隊********************************\n");
printf("出棧元素為%d\n", CirQueue_Dequeue(Manager));
printf("出棧元素為%d\n", CirQueue_Dequeue(Manager));
printf("出棧元素為%d\n", CirQueue_Dequeue(Manager));
printf("出棧元素為%d\n", CirQueue_Dequeue(Manager));
printf("出棧元素為%d\n", CirQueue_Dequeue(Manager));
// //5.遍歷順序迴圈佇列
CirQueue_Print(Manager); // --空
printf("\n");
// 2.向順序迴圈佇列中插入新元素
printf("*********************************入隊********************************\n");
CirQueue_Enqueue(Manager, 6);
CirQueue_Enqueue(Manager, 4);
CirQueue_Enqueue(Manager, 1);
CirQueue_Enqueue(Manager, 2);
CirQueue_Enqueue(Manager, 5);
// //3.遍歷順序迴圈佇列
CirQueue_Print(Manager); // -- 6 4 1 2 5
printf("\n");
return 0;
}