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;
}
}
}