循环顺序队列的建立与操作

一、基本思路

1.初始化建空队列时,令front=rear=0;

2.插入元素时尾指针增1,删除队头元素时头指针增1,;

3.头指针始终指向队头元素,尾指针指向尾元素的下一个位置,如图;

4.臆造环状空间

(1)在a状态下依次插入J5,J6,J7得到b,在a状态下依次删除J3,J4,J5得到c;

(2)队列满或空时都有front=rear,两种解决方法:一是设置标志位,二是预留最后一个空间,作为满的条件;

5.如果用户无法估计队列最大长度,则使用循环链队列;

6.使用一维数组来模拟循环队列要注意rear和front之间的关系,就求队列长度而言,不能直接rear-front,设想这样一种情况

   内存空间是6,填满队列后front为0,rear为5,现在把一个元素出队列,那么front要加1,现在下标为0的空间空出来了,

   现在插入一个元素,rear的值就是0,所以要求此时队列长度,就是(rear-front+max)%max;

二 、代码如下

/*
项目名称:顺序循环队列的建立与基本操作

编译环境:VC++ 2008

作者相关:。。。

最后修改:2019.6.23


学习目标:初始化、销毁、清空、判空、求长、返回队头元素、插入元素、删除元素、输出队列中元素

注意事项:1.测试所有功能是否正常

2.Q.rear-Q.front + MAXQSIZE % MAXQSIZE

一维数组模拟的循环队列,假设有5块内存,front增加到5了,那么5之前的空间可以使用,
这样rear就到1所在的空间,这样rear就比5小了

*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAXQSIZE 100
#define ERROR    0
#define OK       1

typedef int      ElemType;
typedef bool     Status;

typedef struct{

	ElemType *base;//初始化动态分配存储空间
	int front;//若队列不空,指向队列头元素
	int rear;//若队列不空,指向队列尾元素的下一个位置

}SqCQueue;

Status InitQueue(SqCQueue *Q);

Status DestroyQueue(SqCQueue *Q);

Status ClearQueue(SqCQueue *Q);

Status EmptyQueue(SqCQueue Q);

int    LengthQueue(SqCQueue Q);

Status GetHead(SqCQueue Q,ElemType *e);

Status EnQueue(SqCQueue *Q,ElemType e);

Status DeQueue(SqCQueue *Q,ElemType *e);

Status TravelQueue(SqCQueue Q);

void   visit(ElemType c);

int main()
{
	SqCQueue q;
	ElemType e;

	InitQueue(&q);

	if(EmptyQueue(q))
		printf("循环队列为空!\n\n");
	else
		printf("循环队列非空!\n\n");

	srand(time(0));
	for(int i=0;i<10;i++)
	{
		e = rand()%100+1;
		EnQueue(&q,e);
	}
	TravelQueue(q);

	int k = LengthQueue(q);
	printf("循环队列长度为:%d \n\n",k);

	GetHead(q,&e);
	printf("循环队列队首为:%d \n\n",e);

	DeQueue(&q,&e);
	DeQueue(&q,&e);
	printf("循环队列第二次删除的元素为:%d \n\n",e);
	TravelQueue(q);

	EnQueue(&q,101);
	printf("插入新元素后,");
	TravelQueue(q);

	ClearQueue(&q);
	DestroyQueue(&q);

	return 0;
}

Status InitQueue(SqCQueue *Q)
{
	Q->base = (ElemType *)malloc(MAXQSIZE*sizeof(ElemType));
	if(!Q->base)
		return ERROR;
	Q->front = Q->rear = 0;

	return OK;
}

Status DestroyQueue(SqCQueue *Q)
{
	free(Q->base);
	return OK;
}

Status ClearQueue(SqCQueue *Q)
{
	Q->front = Q->rear = 0;

	return OK;
}

Status EmptyQueue(SqCQueue Q)
{
	if(Q.front == Q.rear)
		return true;
	else
		return false;
}

int    LengthQueue(SqCQueue Q)
{
	return (Q.rear-Q.front + MAXQSIZE) % MAXQSIZE;
}

Status GetHead(SqCQueue Q,ElemType *e)
{
	if(EmptyQueue(Q))
		return ERROR;
	else
	{
		*e = *(Q.base+Q.front);
		return OK;
	}
}

Status EnQueue(SqCQueue *Q,ElemType e)
{
	if((Q->rear+1)%MAXQSIZE == Q->front)//队列满,即rear指向front之前的位置时
		return ERROR;

	*(Q->base+Q->rear) = e;
	Q->rear = (Q->rear+1) % MAXQSIZE;//假设max为6,本来rear=5(从0开始计数的),
	//现在要到第一块内存,rear要等于0,实现了循环
	return OK;

}

Status DeQueue(SqCQueue *Q,ElemType *e)
{
	if(EmptyQueue(*Q))
		return ERROR;
	else
	{
		*e = *(Q->base+Q->front);
		Q->front = (Q->front+1) % MAXQSIZE;//指向它的下个位置
		return OK;
	}
}

Status TravelQueue(SqCQueue Q)
{
	printf("顺序循环队列内容: \n\n");
	while(Q.front!=Q.rear)
	{
		visit(*(Q.base+Q.front));
		Q.front = (Q.front+1) % MAXQSIZE;
	}
	printf("\n\n");
	return OK;
}

void   visit(ElemType c)
{
	printf("%d ",c);
}

三、效果

猜你喜欢

转载自blog.csdn.net/Sruggle/article/details/93409182