循环队列:以数组为基础

队列遵循“先进先出”的原则,也被成为 FIFO”结构

数据结构中的队列的两端都允许操作,只不过要求数据只能从队列的一端插入,从队列的另一端删除,可以把队列理解为一根水管,水管有进水口和出水口。一般把允许数据插入的端称为队尾(Tail或者Rear)。一般把允许删除数据的一端称为队头(Head 或者Fron)尾插:enqueue 头删:dequeue

循环队列:

  • 判断空队的条件:队尾下标等于队首下标
  • 判断满队的条件:(队尾下标+1) %容量=队首下标     –>空间换时间的案例
  • 入队需要判断:当前队是否为满的
  • 出队需要判段:当前队是否为空的
/******************************************************************************
*
*   file name : Structure equence
*   author    : Wzy
*   data      : 2025/12/10
*   function  : 实现循环队列
*   note      : None
*
*   copyRight  (c)  2025    17630246607@163.com   All Right Reseverd
* ****************************************************************************/



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

//指的是循环队列中的元素的数据类型,用户可以根据需要进行修改
typedef int DataType_t;

//构造记录循环队列CircularQuence各项参数,(循环队列的首地址+循环队列的容量+循环队列队尾下标+队首下标)
typedef struct CircularQuence
{
	DataType_t    *Addr;     //记录循环队列首元素地址
	unsigned int  Size;     //记录循环队列元素的容量
	int           Rear;    //记录循环队列队尾下标
	int           Front;   //记录循环队列队首下标	

}CirQuence_t;



/******************************************************************************
*
*   func name    : CirQuence_Create
*   function     : 创建并初始化循环队列
*   argument     : 
*                   @size:指定循环队列的初始总容量
*   retval       : 返回初始化后的Manager指针
*   author       : Wzy
*   date         : 2025/12/10
*   note         :	None
* 
* ****************************************************************************/


//1.创建循环队列并对循环队列进行初始化
CirQuence_t * CirQuence_Create(unsigned int size)  
{
    //利用calloc为循环队列的管理结构体申请一块堆内存
	CirQuence_t *Manager = (CirQuence_t *)calloc(1,sizeof(CirQuence_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->Front = 0;  //由于循环队列为空,则队首下标初值为0
	Manager->Rear  = 0;  //由于循环队列为空,则队尾下标初值为0

	return Manager;
}



/******************************************************************************
*
*   func name    : CirQuence_IsFull
*   function     : 判断循环队列是否已满
*   argument     : 
* 					@CirQuence *Manager是管理循环队列的结构体的地址
*   retval       : bool flag :bool型返回值,如果循环队列已满,返回true。没满返回false
*   author       : Wzy
*   date         : 2025/12/10
*   note         : 这个函数是为了后面在循环队列增加元素,如果循环队列满了,就不能在向当前的循环队列中增加元素
* 
* ****************************************************************************/

bool CirQuence_IsFull(CirQuence_t *Manager)
{

	return ( (Manager->Rear + 1) % Manager->Size == Manager->Front) ? true : false;  //循环队列判断满队的条件:(队尾下标+1) %容量 =队首下标     -->空间换时间的案例 
}

/******************************************************************************
*
*   func name    : CirQuence_Enquence
*   function     : 向循环队列尾部中加入元素
*   argument     : 
* 					@SeqList_t *Manager是管理顺序表的结构体的地址
* 					@DataType_t Data:Data是要增加在顺序表中的元素。DataType_t是增加在顺序表中的元素的类型,即元素Data的类型是DataType_t
*   retval       : false:循环队列已满,无法在循环队列中增加元素
* 					true :循环队列未满,已经在循环队列尾部增加了新元素
*   author       : Wzy
*   date         : 2025/12/10
*   note         : None
* 
* ****************************************************************************/

//入队
bool CirQuence_Enquence(CirQuence_t *Manager,DataType_t Data) //CirQuence_t *Manager是管理循环队列的结构体的地址,Data是循环队列中的元素。DataType_t是循环队列中的元素的类型
{
	// 1.判断循环队列是否已满
	if (CirQuence_IsFull(Manager))
	{
		printf("CirQuence is Full!\n");
		return false;
	}
	//2.如果循环队列有空闲空间,则把新元素增加到循环队列尾部

	Manager->Addr[Manager->Rear] = Data;

	//防止队尾下标越界
	Manager->Rear = (Manager->Rear + 1) % Manager->Size;

	return true;
}




/******************************************************************************
*
*   func name    : CirQuence_IsEmpty
*   function     : 判断循环队列是否是空的
*   argument     : 
* 					@CirQuence_t *Manager是管理循环队列的结构体的地址
*   retval       : bool :bool型返回值,如果循环队列是空的,返回true。不是空的返回false
*   author       : Wzy
*   date         : 2025/12/04
*   note         : 这个函数是为了后面删除循环队列中的元素,如果循环队列是空的,就不能在向当前的循环队列中删除元素
* 
* ****************************************************************************/

bool CirQuence_IsEmpty(CirQuence_t *Manager)
{

	return (Manager->Front == Manager->Rear) ? true : false;  // 判断空队的条件:队尾下标等于队首下标

}


/******************************************************************************
*
*   func name    : CirQuence_Dequence
*   function     : 删除循环队列中的尾部元素。
*   argument     : 
* 					@SeqList_t *Manager是管理循环队列的结构体的地址
*   retval       : bool :bool型返回值,如果删除成功,返回true。删除失败返回false
*   author       : Wzy
*   date         : 2025/12/10
*   note         : None
* 
* ****************************************************************************/

//出队

DataType_t  CirQuence_Dequence(CirQuence_t *Manager)
{
	DataType_t temp = 0;  //接收出队的元素
	//1.调用CirQuence_IsEmpty函数判断当前循环队列是否为空
	if(CirQuence_IsEmpty(Manager))
	{
		printf("CirculareQuence is Empty!\n");
		return false;
	}

	//2.把元素从队首出队,并且备份到temp中
	temp = Manager->Addr[Manager->Front];

	//防止队首下标越界
	Manager->Front = (Manager->Front + 1) % Manager->Size;

	return temp;
}


/******************************************************************************
*
*   func name    : CirQuence_Print
*   function     : 遍历循环队列中的元素
*   argument     : 
* 					@CirQuencet_t *Manager是管理循环队列的结构体的地址
*   retval       : None
*   author       : Wzy
*   date         : 2025/12/10
*   note         : None
* 
* ****************************************************************************/

void CirQuence_Print(CirQuence_t *Manager)
{
	 // 1.判断循环队列是否为空
    if (CirQuence_IsEmpty(Manager))
    {
        printf("CircularQuence is Empty! No elements to print.\n");
        return;
    }

    // 2.遍历循环队列(从队首到队尾)
    printf("CircularQuence elements: \n");
    int i = Manager->Front;  // 从队首开始遍历
    while (i != Manager->Rear)  // 遍历到队尾结束
    {
        printf("%d ", Manager->Addr[i]);
        i = (i + 1) % Manager->Size;  // 防止下标越界
    }
    printf("\n");
}





int main(int argc, char const *argv[])
{

// 1.创建容量为5的循环队列(实际可用容量为4,因预留一个空位判满)
    CirQuence_t *queue = CirQuence_Create(5);

    if (NULL == queue)
    {
        printf("Create CircularQuence failed!\n");
        return -1;
    }
    printf("Create CircularQuence success, size: %u\n", queue->Size);

    // 2.入队操作:添加4个元素(达到最大可用容量)
    printf("\n=== Enquence Test ===\n");
    CirQuence_Enquence(queue, 10);
    CirQuence_Enquence(queue, 20);
    CirQuence_Enquence(queue, 30);
    CirQuence_Enquence(queue, 40);
    CirQuence_Print(queue);  // 打印:10 20 30 40

    // 3.测试队列满:尝试入队第5个元素
    printf("\n=== Test Full Queue ===\n");
    if (!CirQuence_Enquence(queue, 50))
    {
        printf("Enquence 50 failed (queue full)\n");
    }
    CirQuence_Print(queue);  // 打印结果不变

    // 4.出队操作:依次出队2个元素
    printf("\n=== Dequence Test ===\n");
    DataType_t data = CirQuence_Dequence(queue);
    printf("Dequence element: %d\n", data);  // 10
    data = CirQuence_Dequence(queue);
    printf("Dequence element: %d\n", data);  // 20
    CirQuence_Print(queue);  // 打印:30 40

    // 5.再次入队:验证循环特性
    printf("\n=== Enquence Again (Circular Test) ===\n");
    CirQuence_Enquence(queue, 50);
    CirQuence_Enquence(queue, 60);
    CirQuence_Print(queue);  // 打印:30 40 50 60

    // 6.清空队列:测试判空
    printf("\n=== Clear Queue Test ===\n");
    while (!CirQuence_IsEmpty(queue))
    {
        data = CirQuence_Dequence(queue);
        printf("Dequence element: %d\n", data);
    }
    CirQuence_Print(queue);  // 打印空队列提示

    // 7.测试空队列出队
    printf("\n=== Test Empty Queue ===\n");
    data = CirQuence_Dequence(queue);
    if (-1 == data)
    {
        printf("Dequence failed (queue empty)\n");
    }

    // 8.释放内存(可选,避免内存泄漏)
    free(queue->Addr);
    free(queue);
    queue = NULL;

    return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇