数据结构 顺序循环队列

队列这种结构再生活中非常常见,从队尾入队,队头出队,利用顺序表来制作一个队列存在一个“假溢出"问题。

什么是假溢出?

当我们用一个数组的开头元素作为队头,而最后一个元素作为队尾;假设在这时整个数组都填满了,然后从这个数组中抽出几个元素,队列的开头其实是空的,但由于尾部已经满了,所以看起来好像整个队列已经”满“了,但是我们都很清楚,在队伍的开头出还有空位,为了解决这个问题,我们采用了一种循环结构的队列。当队尾满时会自动检查队伍前面是否由空位。

由于在使循环队列时,当队头位标等于队尾位标时存在俩种情况,一种是队列是空的,而另外一种可能时队列是满的。

所以我们将队列的一位空出来不去使用,这样就能区分队列到底是空还是满。

下面是队列的结构声明:

typedef int ElemType;
typedef struct{
	ElemType data[MAXSIZE];
	int front;
	int rear; 
}SqQueue;

以Q作为队列结构为例,

计算队列长度的公式 : (rear - front + MAXSIZE) % MAXSIZE

判断队列是否为满的条件:(rear + 1) % MAXSIZE == front

判断队列是否为空的条件: rear == front.

下面是各个操作。 

初始化操作:

void initQueue(SqQueue *Q){
	/* 这个函数用来初始化顺序队列*/ 
	if(Q == NULL){
		printf("空指针无法初始化!!\n");
	}
	else{
		Q->front = 0;
		Q->rear = 0;
		printf("队列初始化成功!!\n");
	}
}

计算队列长度的操作:

int QueueLength(SqQueue *Q){
	/*这个函数用来计算队列的长度*/
	return ((Q->rear - Q->front + MAXSIZE) % MAXSIZE);
}

入队操作:

void EnQueue(SqQueue *Q, ElemType e){
	/*这个函数用来向队列中插入元素*/
	if((Q->rear + 1) % MAXSIZE == Q->front){
		printf("该队列已满,无法再向其中添加元素!!\n");
	}else{
		Q->data[Q->rear] = e;
		Q->rear = (Q->rear + 1) % MAXSIZE;
		printf("该数据成功插入队列!!\n");
	}
}

出队操作:

void DeQueue(SqQueue *Q, ElemType *e){
	/* 这个函数用来删除队列中的队头元素*/
	if(Q->front == Q->rear){
		printf("该队列是空的,没有可以出队的元素!!\n");
	} else{
		*e = Q->data[Q->front];
		Q->front = (Q->front + 1) % MAXSIZE;
		printf("该元素成功清出队列!!\n");
	}
}

打印队列操作:

void PrintQueue(SqQueue *Q){
	/* 这个函数用来打印队列中的内容*/
	if(Q->front == Q->rear){
		printf("该队列是空的!!\n");
	}else{
		if(Q->rear > Q->front){
			int index;
			for(index = Q->front; index < Q->rear; index++){
				printf("%d  ",Q->data[index]);
			}
				printf("\n");
		}else{
			int index = Q->front;
			while((index % MAXSIZE) != Q->rear){
				printf("%d  ", Q->data[index]);
				index = (index + 1) % 5;
			}
			printf("\n");
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值