队列Queue
队列的顺序存储实现
这里对rear和front位置无要求。
如果空队列开始时front和rear值都是-1,当插入4个元素并删除2个元素后,front和rear值分别是多少?1和3
现采用大小为10的数组实现一个循环队列。设在某一时刻,队列为空且此时front和rear值均为5。经过若干操作后,front为8,rear为2,问:此时队列中有4个元素。
通用的队列长度计算公式:队列长度=(rear - front + MaxSize) % MaxSize
解释:front、rear方向一致,front指向实际存在的结点的前一个结点,rear指向实际存在的最后一个结点,此时队列中有9、0、1、2四个位置上的元素。
《数据结构》课程给出的队列顺序存储实现方式如下:
typedef int Position;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef struct QNode *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("队列满");
return false;
}
else {
Q->Rear = (Q->Rear+1)%Q->MaxSize;
Q->Data[Q->Rear] = X;
return true;
}
}
bool IsEmpty( Queue Q )
{
return (Q->Front == Q->Rear);
}
ElementType DeleteQ( Queue Q )
{
if ( IsEmpty(Q) ) {
printf("队列空");
return ERROR;
}
else {
Q->Front =(Q->Front+1)%Q->MaxSize;
return Q->Data[Q->Front];
}
}
测试程序如下:
#include <stdio.h>
#include <stdbool.h>
#define ERROR 0
typedef int ElementType;
typedef struct QNode *Queue;
struct QNode
{
ElementType *Data;
int MaxSize;
int front;
int rear;
};
Queue CreateQueue(int MaxSize)
{
Queue q = (Queue)malloc(sizeof(struct QNode));
q->Data = (ElementType*)malloc(sizeof(ElementType)*MaxSize);
q->front = 0;
q->rear = 0;
q->MaxSize = MaxSize;
return q;
}
bool IsFullQ(Queue q)
{
return (((q->rear+1)%q->MaxSize) == q->front);
}
bool AddQ(Queue q,ElementType item)
{
if(IsFullQ(q))
{
printf("队列已满\n");
return false;
}
else
{
q->rear = (q->rear+1)%(q->MaxSize);
q->Data[q->rear] = item;
return true;
}
}
bool IsEmptyQ(Queue q)
{
return (q->rear == q->front);
}
ElementType DeleteQ(Queue q)
{
if(IsEmptyQ(q))
{
printf("队列为空\n");
return ERROR;
}
else
{
q->front = (q->front+1)%(q->MaxSize);
return (q->Data[q->front]);
}
}
int main()
{
Queue q = CreateQueue(10);
int choice;
while(1)
{
printf("输入1添加1个元素,输入2删除1个元素,输入0结束循环\n");
scanf("%d",&choice);
if(choice == 1)
{
ElementType X;
scanf("%d",&X);
AddQ(q,X);
}
else if(choice == 2)
{
ElementType X = DeleteQ(q);
printf("%d\n",X);
}
else
return 0;
}
}
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
2
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
3
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
1
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
4
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
5
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
6
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
2
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
3
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
1
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
4
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
5
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
6
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
队列为空
0
输入1添加1个元素,输入2删除1个元素,输入0结束循环
0
Process returned 0 (0x0) execution time : 56.625 s
Press any key to continue.
队列的链式存储实现
队列的front只能设在链表头部。如果front放在链表尾部,删除当前结点后无法找到上一个结点。
在一个链表表示的队列中, f和r分别指向队列的头和尾。r->next=s; r=s;
能正确地将s结点插入到队列中。
《数据结构》课程给出的队列链式存储实现方式如下:
typedef struct Node *PtrToNode;
struct Node { /* 队列中的结点 */
ElementType Data;
PtrToNode Next;
};
typedef PtrToNode Position;
struct QNode {
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef struct QNode *Queue;
bool IsEmpty( Queue Q )
{
return ( Q->Front == NULL);
}
ElementType DeleteQ( Queue Q )
{
Position FrontCell;
ElementType FrontElem;
if ( IsEmpty(Q) ) {
printf("队列空");
return ERROR;
}
else {
FrontCell = Q->Front;
if ( Q->Front == Q->Rear ) /* 若队列只有一个元素 */
Q->Front = Q->Rear = NULL; /* 删除后队列置为空 */
else
Q->Front = Q->Front->Next;
FrontElem = FrontCell->Data;
free( FrontCell ); /* 释放被删除结点空间 */
return FrontElem;
}
}
测试程序如下:
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#define ERROR 0
typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node
{
ElementType Data;
PtrToNode Next;
};
PtrToNode CreateNode(ElementType Data)
{
PtrToNode newNode = (PtrToNode)malloc(sizeof(struct Node));
assert(newNode);
newNode->Data = Data;
newNode->Next = NULL;
return newNode;
}
typedef PtrToNode Position;
typedef struct QNode *Queue;
struct QNode
{
PtrToNode Front,Rear;
int curSize;
};
Queue CreateQueue()
{
Queue q = (Queue)malloc(sizeof(struct QNode));
assert(q);
q->curSize = 0;
q->Front = q->Rear = NULL;
return q;
}
void AddQ(Queue q,ElementType item)
{
//PtrToNode s = (PtrToNode)malloc(sizeof(struct Node));
//s->Data = item;
//s->Next = NULL;
PtrToNode s = CreateNode(item);
if(q->curSize == 0)
q->Front = s;
else
q->Rear->Next = s;
q->Rear = s;
q->curSize++;
}
bool IsEmptyQ(Queue q)
{
return (q->Front == NULL);
}
ElementType DeleteQ(Queue q)
{
PtrToNode FrontCell;
ElementType FrontElem;
if(IsEmptyQ(q))
{
printf("队列空!\n");
return ERROR;
}
else
{
FrontCell = q->Front;
if(q->Front == q->Rear)
q->Front = q->Rear = NULL;
else
q->Front = q->Front->Next;
FrontElem = FrontCell->Data;
free(FrontCell);
q->curSize--;
return FrontElem;
}
}
int main()
{
Queue q = CreateQueue();
int choice;
while(1)
{
printf("输入1添加1个元素,输入2删除1个元素,输入0结束循环\n");
scanf("%d",&choice);
if(choice == 1)
{
ElementType X;
scanf("%d",&X);
AddQ(q,X);
}
else if(choice == 2)
{
ElementType X = DeleteQ(q);
printf("%d\n",X);
}
else
return 0;
}
}
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
2
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
3
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
4
输入1添加1个元素,输入2删除1个元素,输入0结束循环
1
5
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
2
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
3
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
4
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
5
输入1添加1个元素,输入2删除1个元素,输入0结束循环
2
队列空!
0
输入1添加1个元素,输入2删除1个元素,输入0结束循环
0
Process returned 0 (0x0) execution time : 22.052 s
Press any key to continue.
如何用两个堆栈模拟实现一个队列?
如何用两个堆栈模拟实现一个队列? 如果这两个堆栈的容量分别是m和n(m>n),你的方法能保证的队列容量是多少?