順序迴圈佇列的介面設計

藍桉未遇釋槐鳥發表於2024-04-26
/********************************************************************************************************
 *
 *
 * 該程式實現迴圈佇列元素的增刪改查,目的是提高設計程式的邏輯思維,另外為了提高可移植性,所以迴圈佇列中元素
 * 的資料型別為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;
}

相關文章