[数据结构题目]14.用标志域表示队空队满状态的循环队列的综合操作(**)

14.用标志域表示队空队满状态的循环队列的综合操作(**)
描述

要求循环队列不损失一个空间全部都得到利用,设置一个标志域tag,以0和1来区分当队头与队尾指针相同时队列状态的空和满,试编写与此结构相对应的入队和出队操作。

(1)教材中为区分当队头与队尾指针相同时队列状态的空和满,以牺牲一个空间的代价来实现的,空:Q->front == Q->rear,满:(Q->rear+1)%MAXSIZE == Q->front。

(2)本题不损失一个空间,全部都得到利用,为此如下定义循环队列类型:

  Typedef struct 

  { QueueElementType element[MAXSIZE];

    int front;

    int rear;

    int tag;

   }SeqQueue;  

此时,循环队列空和满的条件分别为: Q->front == Q->rear&&tag == 0 和Q->front == Q->rear&&tag == 1

(3)编写入队函数、出队函数。

(4)在主函数中编写菜单(1.入队;2.出队;3.退出),调用上述功能函数。

代码如下:

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

#define error 0
#define OK 1
#define FALSE -1
#define TRUE 1
#define scanf_s scanf
#define MAXSIZE 10
typedef int SeqQueueElemType;


typedef struct queue{
	SeqQueueElemType elem[MAXSIZE];
	int front;//头指针
	int rear;//尾指针
	int tag;//标志域
}SeqQueue; //定义队头

void Initqueue(SeqQueue *bt);
int EnterQueue(SeqQueue *bt,SeqQueueElemType x);
int DeleteQueue(SeqQueue *bt,SeqQueueElemType *x);
int printSeqQueue(SeqQueue *bt,int i);
int main();

void Initqueue(SeqQueue *Q)//循环队列初始化操作
{
	Q->front=Q->rear=0;   //初始化时,队列的头尾指针都指在下表为0处
	Q->tag=0;             //taq置0.表示对列为空
}
/*TODO:元素加入到队列
 功能描述:如果队头和队尾相等并且tag为1,提示队列已经满printf("操作提示:队已满!");并返回error
 不满的情况下,把元素加入到队列elem中,增加队尾值,打印提示元素已加入队列printf("操作提示:%d 已入队!",x);
 如果此时队头和队尾相等,则设置tag为1,表示队列已满
 参数说明:Q-SeqQueue型的队列指针变量
       x-SeqQueueElemType型的待加入到队列的元素
 返回值说明:成功返回TRUE 队列已满返回error
 */
int EnterQueue(SeqQueue *Q, SeqQueueElemType x)
{
    if(Q->front == Q->rear && Q->tag == 1)
    {
        printf("操作提示:队已满!");
        return error;
    }
    else
    {
        Q->elem[Q->rear] = x;
        Q->rear = (Q->rear+1) % MAXSIZE;//通过求模运算实现循环
        printf("操作提示:%d 已入队!",x);
        if(Q->front == Q->rear)  //如果此时队头和队尾相等,则设置tag为1,表示队列已满
        {
            Q->tag = 1;
        }
    }
}
/*TODO:元素出列
 功能描述:如果队头和队尾相等并且tag为0,提示队列已经空了printf("操作提示:队为空!");并返回error
 不空的情况下,把头部元素赋值给x,打印提示头部元素已出队列printf("操作提示:%d 已出队!",tmp);增加队头值
 如果此时队头和队尾相等,则设置tag为0,表示队列为空
 参数说明:Q-SeqQueue型的队列指针变量
       x-SeqQueueElemType型的出队元素指针
 返回值说明:成功返回TRUE 队列已空返回error
 */
int DeleteQueue(SeqQueue *Q, SeqQueueElemType *x)
{
    if(Q->front == Q->rear && Q->tag == 0)
    {
        printf("操作提示:队为空!");
        return error;
    }
    else
    {
        *x = Q->elem[Q->front];
        Q->front = (Q->front+1) % MAXSIZE;
        printf("操作提示:%d 已出队!",*x);
        if(Q->front == Q->rear)   //如果此时队头和队尾相等,则设置tag为0,表示队列为空
        {
            Q->tag = 0;
        }
    }
}
int printSeqQueue(SeqQueue *Q,int count)
{
	int n;
	if((Q->front==Q->rear)&&(Q->tag==0))
		printf("操作提示:队列为空!");
	else
	{
		printf("操作结果:");
		for(n=Q->front;count>0;n++)
			{
				printf("%d ",Q->elem[n]);
				count--;
			}
	}
	return TRUE;
}


int main()
{
	SeqQueue Q;
	int i=1,count=0;     //count记录队列中剩余数据
	SeqQueueElemType x;
	Q.front=Q.rear=0;
	Q.tag=0;  //在主函数提前置空队列,防止程序异常结束。 tag=0;
	while(i)
	{
			printf("\n*****************");
			printf("\n*       menue   *");
			//printf("\n*1    置空队列  *");
			printf("\n*1      入队    *");
			printf("\n*2      出队    *");
			//printf("\n*4    打印队列  *");
			printf("\n*3      退出    *");
			printf("\n*****************\n");
			printf("请选择:");
		scanf_s("%d",&i);
		switch(i)
		{
			case 1:
				printf("请输入数据:");
				scanf_s("%d",&x);
				EnterQueue(&Q,x);
				count++;				//每输入一个数据,数据剩余记录+1
				if (count>MAXSIZE)		//如果数据超出限制,则限制count为最大值 防止输出溢出
					count=MAXSIZE;
				break;
			case 2:
				DeleteQueue(&Q,&x);
				count--;//每出列一个数据,队列中剩余数据-1
				break;
			case 3:
				printf("操作提示:再见\n");
				return 0;
			default:
				printf("操作提示:选择错误,请重新选择!");
				break;
		}
	}
}


posted @ 2020-04-01 22:15  Desola  阅读(886)  评论(0编辑  收藏  举报