“队列”类似于堆栈,也是一个有序的线性表。不同于堆栈的插入和删除操作只在一端操作的方式,队列的插入和删除分别在线性表的不同端点进行。
队列的顺序存储结构的可以定义为:
typedef int ElementType;
typedef int Position;
typedef struct QNode* PtrToQNode;
struct QNode
{
ElementType* Data;
Position Front, Rear;
int MaxSize;
};
typedef PtrToQNode Queue;
其中,在写代码时留意到的几个关键点:
1)注意,定义中,队头Front实际指向的是队列第一个元素前边的那个那块区域,而队尾Rear指向的是队列的最后一个元素。
2)为了避免假溢出,使用了循环队列的方式。队列的最大容量MaxSize并不是队列中实际能存放元素的最大数量!因为如果满队列的状态如下图C所示,其能存放元素的最大数量应该为MaxSize-1
3)由循环列表的特殊性决定了以下两个操作:
入队→Q->Rear = (Q->Rear+1)%Q->MaxSize;
出队→Q->Front = (Q->Front+1)%Q->MaxSize
完整操作代码如下:
/*队列的ADT:
1、类型名:队列(Queue)
2、数据对象及:一个有0个或多个元素的有穷线性表
3、操作集:
对于一个长度为正整数MaxSize的队列Q∈Queue,记队列中的任一元素X∈ElementType,队列的基本操作有
(1)Queue CreateQueue(int MaxSize):生成空队列,其最大长度为MaxSize
(2) bool IsFull(Queue Q):判断队列Q是否已满
(3)bool IsEmpty(Queue Q):判断队列Q是否是空的
(4)bool AddQ(Queue Q,ElementType X):将元素X压入队尾。若队列已满,返回false
(5)ElementType DeleteQ(Queue Q):从队列Q的队头弹出元素。若队列为空,返回错误信息
(6)void QueueRead():将一些元素入队,若入队的元素的个数大于队列的最大容量,只入队满队列
(7) int QueueLength(Queue Q):输出队列中元素的个数
(8)void QueuePrint(Queue Q):将队列中的元素从队头到队尾依次输出 */
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define Error -1
typedef int ElementType;
typedef int Position;
typedef struct QNode* PtrToQNode;
struct QNode
{
ElementType* Data;
Position Front, Rear;
int MaxSize;
};
typedef PtrToQNode Queue;
Queue CreateQueue(int MaxSize)
{
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType));
Q->Front = Q->Rear = 0;
Q->MaxSize = MaxSize;
return Q;
}
bool IsFull(Queue Q)
{
return ((Q->Rear + 1) % Q->MaxSize == Q->Front);
}
bool AddQ(Queue Q, ElementType X)
{
if (IsFull(Q))
{
printf("队列已满\n");
return false;
}
else
{
Q->Rear = (Q->Rear + 1) % Q->MaxSize;
Q->Data[Q->Rear] = X;
return true;
}
}
void QueueRead(Queue Q)
{
if (IsFull(Q))
{
printf("队列已满\n");
return;
}
int num, elem;
int sig;
printf("请输入要入队的元素的个数:\n");
scanf("%d", &num);
printf("请输入要入队的各个元素:\n");
while (num--)
{
scanf("%d", &elem);
sig = AddQ(Q, elem);
if (!sig)
break;
}
}
bool IsEmpty(Queue Q)
{
return (Q->Front == Q->Rear);
}
ElementType DeleteQ(Queue Q)
{
if (IsEmpty(Q))
{
printf("队列是空的,无元素\n");
return Error;
}
else
{
Q->Front = (Q->Front + 1) % Q->MaxSize;
return Q->Data[Q->Front];
}
}
int QueueLength(Queue Q)
{
if (Q->Rear < Q->Front)
return (Q->Rear + Q->MaxSize - Q->Front);
else
return(Q->Rear - Q->Front);
}
void QueuePrint(Queue Q)
{
if (IsEmpty(Q))
{
printf("队列是空的");
return;
}
int i = Q->Front;
int j = Q->Rear;
while (i != j)
{
i = (i + 1) % (Q->MaxSize);
printf("%d ", Q->Data[i]);
}
}
int main()
{
//设定队列的最大容量
int maxsize;
printf("请输入队列数组的最大容量:");
scanf("%d", &maxsize);
printf("该队列最多入队%d个元素\n", maxsize - 1);
//创建一个顺序存储的队列
Queue Q = CreateQueue(maxsize);
printf("此时队列中元素的个数为:%d\n", QueueLength(Q));
//选择将元素入队
QueueRead(Q);
printf("队列中元素的个数为:%d\n", QueueLength(Q));
//输出队列中的各个元素(从队头到对位)
QueuePrint(Q);
printf("\n\n");
printf("请您选择出队元素的个数:\n");
int length;
scanf("%d", &length);
if (length>QueueLength(Q))
{
printf("您选择数超过了队列元素个数,错误!!!\n");
return 0;
}
if (length == 0)
{
printf("没有任何元素需要出队\n");
}
else
{
int elem;
printf("从队头到队尾,出列的元素分别为:\n");
while (length--)
{
elem = DeleteQ(Q);
printf("%d ", elem);
}
printf("\n");
}
printf("出队后,队列的长度为:%d\n", QueueLength(Q));
printf("出队后,队列中的元素为:");
QueuePrint(Q);
printf("\n");
return 0;
}