【循环顺序队列】

文章目录

  • 概念
  • 一、循环顺序队列算法
  • 二、算法的实现
    • 1.循环队列初始化
    • 2.入栈
    • 3.出队
    • 4.队列是否已满
    • 5.队列是否为空
    • 6.队列长度
    • 7.取队首元素
    • 8.输出队列元素
  • 三、完整Demo
  • 四、总结


概念

        循环顺序队列即顺序存储的队列,是为了避免 "假溢出"而利用%运算符将队列首尾相接连成一个环状的队列。
        循环顺序队列中,当队尾指针到达数组末端时,如果队头指针指向的元素不是空,那么队尾指针就会从数组的开始继续移动;如果队头指针指向的元素是空,那么队头指针就会从数组的末尾开始移动。循环顺序队列可以有效地利用数组空间,避免因为假溢出而造成空间的浪费。

一、循环顺序队列算法

        循环顺序队列通常使用一个一维数组实现,其基本操作包括入队、出队、判断队列是否为空、判断队列是否已满等。
以下是循环顺序队列的基本算法:

1、初始化:设定一个数组用于存储队列元素,并设定两个指针,一个指向队头元素,一个指向队尾元素的下一个位置。

2、入队操作:将元素添加到队尾,并将队尾指针后移一位。如果队尾指针已经到达数组末端,则将其循环移动到数组开头。
3、出队操作:将队头元素出队,并将队头指针后移一位。如果队头指针已经到达数组末端,则将其循环移动到数组开头。
4、判断队列是否为空:检查队头指针和队尾指针是否重合。如果重合,则队列为空。

5、判断队列是否已满:检查队尾指针和队头指针的差值是否等于数组长度减一,如果等于,则队列已满。

以上是循环顺序队列的基本算法。在实际应用中,可以根据需要进行修改和扩展。

二、算法的实现

  • 1.循环队列初始化
  • int init(CirclesQueue *Q) {
        Q->front = Q->rear = 0;
        return 0;
    }
  • 2.入栈
  • int enqueue(CirclesQueue *Q, DataType x) {
        if (isfull(Q)) {
            printf("队列已满!100001\n");
            return 100001;
        }
    
        Q->rear = (Q->rear + 1) % MAXSIZE;
        Q->data[Q->rear] = x;
        return 0;
    }
  • 3.出队
  • int dequeue(CirclesQueue *Q, DataType *x) {
        if (isempty(Q)) {
            printf("队列为空!100002\n");
            return 100002;
        }
        Q->front = (Q->front + 1) % MAXSIZE;
        *x = Q->data[Q->front];
        return 0;
    }
  • 4.队列是否已满
  • int isfull(CirclesQueue *Q) {
        return (Q->rear + 1) % MAXSIZE == Q->front ? 1 : 0;
    }
  • 5.队列是否为空
  • int isempty(CirclesQueue *Q) {
        return (Q->front == Q->rear) ? 1 : 0;
    }
  • 6.队列长度
  • int getLength(CirclesQueue *Q, DataType *length) {
        *length = (Q->rear - Q->front + MAXSIZE) % MAXSIZE;
        return 0;
    }
  • 7.取队首元素
  • int getHead(CirclesQueue *Q, DataType *x) {
        if (isempty(Q)) {
            printf("队列为空!100002\n");
            return 100002;
        }
        *x = Q->data[(Q->front + 1) % MAXSIZE];
        return 0;
    }
  • 8.输出队列元素
  • void printQueue(CirclesQueue *Q) {
        if (isempty(Q)) {
            printf("队列为空!\n");
            return;
        }
        int front = (Q->front + 1) % MAXSIZE;
        while (front != (Q->rear + 1) % MAXSIZE) {
            printf("%d", Q->data[front]);
            front = (front + 1) % MAXSIZE;
        }

三、完整Demo

1.CirclesQueue.h
#define MAXSIZE 100

typedef int DataType;

typedef struct
{
	DataType data[MAXSIZE];
	int front;
	int rear;
}CirclesQueue;

/*循环队列初始化*/
int init(CirclesQueue *Q);

/*入队*/
int enqueue(CirclesQueue *Q, DataType x);

/*队满*/
int isfull(CirclesQueue *Q);

/*出队*/
int dequeue(CirclesQueue *Q, DataType *);

/*队空*/
int isempty(CirclesQueue *Q);

// 输出队列内容  
void printQueue(CirclesQueue *Q);

// 获取队列长度  
int getLength(CirclesQueue *Q);

// 获取队首元素
DataType getFront(CirclesQueue* Q);
2.CirclesQueue.c
#include <stdio.h>
#include "CirclesQueue.h"

/*循环队列初始化*/
int init(CirclesQueue *Q)
{
	Q->front = Q->rear = 0;
	return 0;
}


/*入队*/
int enqueue(CirclesQueue *Q, DataType x)
{
	if(isfull(Q))
	{
		printf("队列已满!100001\n");
		return 100001;
	}

	Q->rear = (Q->rear+1) % MAXSIZE;
	Q->data[Q->rear] = x;
	return 0;
}

/*队满*/
int isfull(CirclesQueue *Q)
{
	return (Q->rear+1)%MAXSIZE == Q->front ? 1 : 0;
}


/*出队*/
int dequeue(CirclesQueue *Q, DataType *x)
{
	if(isempty(Q))
	{
		printf("队列为空!100002\n");
		return 100002;
	}
	Q->front = (Q->front+1) % MAXSIZE;
	*x = Q->data[Q->front];
	return 0;
}

/*队空*/
int isempty(CirclesQueue *Q)
{
	return (Q->front == Q->rear) ? 1 : 0;
}

// 输出队列内容  
void printQueue(CirclesQueue *Q) {
    int i;
    if (isempty(Q)) {  
        printf("Queue is empty.\n");  
        return;  
    }  
    i = (Q -> front) %MAXSIZE;
    do{
        printf(" %d",Q -> data[(i + 1 % MAXSIZE)]);
        i = (i+1) %MAXSIZE;
    }while(i != Q -> rear);
}

// 获取队列长度  
int getLength(CirclesQueue *Q) {  
    return (Q->rear - Q->front + MAXSIZE) % MAXSIZE; 
} 

// 获取队首元素  
DataType getFront(CirclesQueue* Q) {  
    int i;
    i = (Q -> front) %MAXSIZE;
    return Q -> data[(i + 1 % MAXSIZE)];
}
3.main.c
#include <stdio.h>
#include "CirclesQueue.h"
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
	CirclesQueue Q;
	DataType x;
	int cmd;
	char yn;
int result;
    char welcome[] = "Start Operation";
	int i = 0; 
	int m = 0; 
	int n = 0;
    for(i=0;i<strlen(welcome);i++)
	{
		printf("%c",welcome[i]);
		for(m=0;m<10000;m++)
			for(n=0;n<1000;n++)
			{
				;
			}
	}
	printf("\n\n\n");

	do
	{	
		printf("-----------Demo演示-----------\n");
		printf(" 1. 初始化\n");
		printf(" 2. 入队\n");
		printf(" 3. 出队\n");
		printf(" 4. 队空\n");
		printf(" 5. 队满\n");
		printf(" 6. 队列元素个数\n");
		printf(" 7. 取队首元素\n");
		printf(" 8. 输出队列\n");
		printf(" 9. 帮助\n");
		printf(" 0. 退出\n");
		printf(" 请选择(0~6):");
		scanf("%d",&amp;cmd);
		switch(cmd)
		{
		case 1:
			init(&amp;Q);
			printf("队列已初始化!\n");
			break;
		case 2:
			printf("请输入要入队的元素x=");
			scanf("%d", &amp;x);
			if(!enqueue(&amp;Q,x))
			{
				printf("元素x=%d已入队\n", x);
			}
			break;
		case 3:
			printf("确定要出队(出队会将删除对首元素, y or n, n)?");
			getchar();
			scanf("%c", &amp;yn);

			if(yn == 'y' || yn == 'Y')
			{
				if(!dequeue(&amp;Q,&amp;x))
				{
					printf("队首元素【%d】已出队!\n", x);
				}
			}
			break;
	    case 4:
			if(isempty(&amp;Q)) printf("队列为空!\n");
			else printf("队列不为空!\n");
			break;
		case 5:
			if(isfull(&amp;Q)) printf("队列已满!\n");
			else printf("队列还没有满!\n");
			break;
		case 6:
			printf("队列的长度:%d\n",getLength(&amp;Q));
			break;
		case 7:
		    printf("队列首元素: %d\n", getFront(&amp;Q));  
            break;
		case 8:
			printf("输出队列:");
			printQueue(&amp;Q);
			printf("\n");
			break;
		case 9:
		    printf("本程序演示到此结束,感谢观看。\n");
		    break;
		}

	}while(cmd!=0);


	return 0;
}

运行截图:


总结

  1. 循环顺序队列的基本概念:了解什么是循环顺序队列,掌握其特点和使用场景。
  2. 循环顺序队列的原理:理解循环顺序队列的原理,包括如何实现循环移动、如何进行入队和出队操作等。
  3. 循环顺序队列的应用:学习循环顺序队列的应用场景,如广度优先搜索、深度优先搜索等。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值