循环队列
#include<stdio.h>
#define MaxSize 100
typedef int ElemType;
typedef struct {
ElemType data[MaxSize];
int front, rear;
}SqQueue;
//初始化队列
void InitQueue(SqQueue& Q) {
Q.rear = Q.front = 0;
}
//判队列空
bool QueueEmpty(SqQueue Q) {
return Q.front == Q.rear;
}
//入队
bool EnQueue(SqQueue& Q, ElemType e) {
if ((Q.rear + 1) % MaxSize == Q.front) {
return false;
}
Q.data[Q.rear] = e;
Q.rear = (Q.rear + 1) % MaxSize;
return true;
}
//出队
bool DeQueue(SqQueue& Q, ElemType& e) {
if (Q.front == Q.rear) {
return false;
}
e = Q.data[Q.front];
Q.front = (Q.front + 1) % MaxSize;
return true;
}
//读队头元素
bool GetHead(SqQueue Q, ElemType &e) {
if (Q.front == Q.rear) {
return false;
}
e = Q.data[Q.front];
return true;
}
//队长
int Length(SqQueue Q) {
return (Q.rear + MaxSize - Q.front) % MaxSize;
}
int main() {
SqQueue Q;
InitQueue(Q);
printf("empty=%d\n", QueueEmpty(Q));
EnQueue(Q, 1);
EnQueue(Q, 2);
EnQueue(Q, 3);
int e;
DeQueue(Q, e);
printf("e = %d\n", e);
GetHead(Q, e);
printf("e = %d\n", e);
printf("empty=%d\n", QueueEmpty(Q));
}
自行实现: 如果初始化队尾指针指向数组最后一个元素即Q.front = 0 Q.rear = MaxSize-1,实现以上函数
判空和判满的方法
a.牺牲一个存储单元
typedef struct {
ElemType data[MaxSize];
int front, rear;
}SqQueue;
//初始化队列
void InitQueue(SqQueue& Q) {
Q.rear = Q.front = 0;
}
//判队列空
bool QueueEmpty(SqQueue Q) {
return Q.front == Q.rear;
}
//判队列满
bool QueueFull(SqQueue Q){
return (Q.rear+1)%MaxSize == Q.front;
}
b.增加一个存储空间
typedef struct {
ElemType data[MaxSize];
int front, rear;
int size;
}SqQueue;
//初始化队列
void InitQueue(SqQueue& Q) {
Q.rear = Q.front = 0;
Q.size = 0;
}
//判队列空
bool QueueEmpty(SqQueue Q) {
return Q.size == 0;
}
//判队列满
bool QueueFull(SqQueue Q){
return Q.size = MaxSize;
}
增加tag=0/1用于标记最近一次操作是 出队/入队
typedef struct {
ElemType data[MaxSize];
int front, rear;
int tag;
}SqQueue;
//初始化队列
void InitQueue(SqQueue& Q) {
Q.rear = Q.front = 0;
Q.size = 0;
}
//判队列空
bool QueueEmpty(SqQueue Q) {
return Q.tag == 0;
}
//判队列满
bool QueueFull(SqQueue Q){
return Q.tag = 1;
}
链队
带头结点
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
typedef int ElemType;
typedef struct LinkNode{
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct LinkQueue {
LinkNode* front, * rear;
};
//初始化队列
void InitQueue(LinkQueue& Q) {
Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
Q.front->next = NULL;
}
//判队列空
bool QueueEmpty(LinkQueue Q) {
return Q.front->next == NULL;
}
//入队
bool EnQueue(LinkQueue& Q, ElemType e) {
LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
if (s == NULL) {
return false;
}
s->data = e;
s->next = NULL;
Q.rear->next = s;
Q.rear = s;
return true;
}
//出队
bool DeQueue(LinkQueue& Q, ElemType& e) {
if (Q.front->next == NULL) {
return false;
}
LinkNode* s = Q.front->next;
e = s->data;
Q.front->next = s->next;
if(Q.rear == s){
Q.rear = Q.front;
}
free(s);
return true;
}
//读取队头元素
bool GetHead(LinkQueue Q, ElemType& e) {
if (Q.front->next == NULL) {
return false;
}
e = Q.front->next->data;
return true;
}
//队列长
int Length(LinkQueue Q) {
LinkNode* s = Q.front->next;
int len = 0;
while (s) {
s = s->next;
len++;
}
return len;
}
int main() {
LinkQueue Q;
InitQueue(Q);
printf("empty=%d\n", QueueEmpty(Q));
EnQueue(Q, 1);
EnQueue(Q, 2);
EnQueue(Q, 3);
int e;
DeQueue(Q, e);
printf("e = %d\n", e);
GetHead(Q, e);
printf("e = %d\n", e);
printf("empty=%d\n", QueueEmpty(Q));
}
不带头结点
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
typedef int ElemType;
typedef struct LinkNode{
ElemType data;
struct LinkNode *next;
}LinkNode;
typedef struct LinkQueue {
LinkNode* front, * rear;
};
//初始化队列
void InitQueue(LinkQueue& Q) {
Q.front = Q.rear = NULL;
}
//判队列空
bool QueueEmpty(LinkQueue Q) {
return Q.front == NULL;
}
//入队
bool EnQueue(LinkQueue& Q, ElemType e) {
LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
if (s == NULL) {
return false;
}
s->data = e;
s->next = NULL;
if (Q.front == NULL) {
Q.front = Q.rear = s;
}
else {
Q.rear->next = s;
Q.rear = s;
}
return true;
}
//出队
bool DeQueue(LinkQueue& Q, ElemType& e) {
if (Q.front == NULL) {
return false;
}
if (Q.front == Q.rear) {
Q.rear = NULL;
}
LinkNode* s = Q.front;
e = s->data;
Q.front = s->next;
if(Q.rear == s){
Q.rear = Q.front = NULL;
}
free(s);
return true;
}
//读取队头元素
bool GetHead(LinkQueue Q, ElemType& e) {
if (Q.front == NULL) {
return false;
}
e = Q.front->data;
return true;
}
//队列长
int Length(LinkQueue Q) {
LinkNode* s = Q.front;
int len = 0;
while (s) {
s = s->next;
len++;
}
return len;
}
int main() {
LinkQueue Q;
InitQueue(Q);
printf("empty=%d\n", QueueEmpty(Q));
EnQueue(Q, 1);
EnQueue(Q, 2);
EnQueue(Q, 3);
int e;
DeQueue(Q, e);
printf("e = %d\n", e);
GetHead(Q, e);
printf("e = %d\n", e);
printf("empty=%d\n", QueueEmpty(Q));
printf("len = %d\n", Length(Q));
DeQueue(Q, e);
printf("e = %d\n", e);
DeQueue(Q, e);
printf("e = %d\n", e);
printf("empty=%d\n", QueueEmpty(Q));
}
注:如果需要多次使用Length函数,可在LinkQueue结构体中增加一个len 元素记录队列长度
提升
//Q为队列,S为空栈,将队列中的元素逆置
void reverse(Queue Q, Stack S){
while(!QueueEmpty(Q)){
DeQueue(Q,x);//队中元素全部出队,压入栈中
Push(S,x);
}
while(!StackEmpty(S)){
Pop(S,x);//栈中元素全部出,存入队中
EnQueue(Q,x);
}
}
利用两个栈S1,S2来模拟一个队列,已知栈的4个运算定义如下:
Push(S,x) ;//元素x入栈s
Pop(S,x) ;//S出栈并将出栈的值赋给x
StackEmpty(S) ;//判断栈是否为空
StackOverflow (S) ;//判断栈是否满
如何利用栈的运算来实现该队列的3个运算(形参由读者根据要求自己设计)?
Enqueue;//将元素x入队
Dequeue;//出队,并将出队元素存储在x中
QueueEmpty;//判断队列是否为空
bool Enqueue(Stack S1, Stack S2, ElemType e){
if(StackOverflow(S1)){
if(!StackEmpty(S2))
return false;
while(!StackEmpty(S1)&&!StackOverflow(S2)){
Pop(S1,x);
Push(S2,x);
}
}
Push(S1,e);
return true;
}
bool Dequeue(Stack S1, Stack S2, ElemType &e){
if(StackEmpty(S2)){
if(StackEmpty(S1)){
return false;
}
while(!StackEmpty(S1)){
Pop(S1,x);
Push(S2,x);
}
}
Pop(S2,e);
return true;
}
bool QueueEmppty(Stack S1, Stack S2){
return StackEmpty(S1)&&StackEmpty(S2);
}
[2019统考真题]请设计一个队列,要求满足:①初始时队列为空;②入队时,允许增加
队列占用空间;③出队后,出队元素所占用的空间可重复使用,即整个队列所占用的空间
只增不减;④入队操作和出队操作的时间复杂度始终保持为0(1)。 请回答下列问题:
1)该队列是应选择链式存储结构,还是应选择顺序存储结构?
2)画出队列的初始状态,并给出判断队空和队满的条件。
3)画出第一个元素入队后的队列状态。
4)给出入队操作和出队操作的基本过程。
解答:
Queue q;
Queue q1;//客车
Queue q2;//货车
void Manager() {
int i = 0, j = 0;
while (j < 10) {
if (!QueueEmpty(q1) && i < 4) {//客车还有并且上船数小于4个,客车上一个
i++;
j++;
ElemType e;
DeQueue(q1, e);
EnQueue(q, e);
}
else if (!QueueEmpty(q2)) {//当客车没有了或客车上船数等于4个且货车还有,货车上一个
i = 0;
j++;
ElemType e;
DeQueue(q2, e);
EnQueue(q, e);
}
else if(i==4){//当货车没有了,但客车还有,,i=0继续上客车
i = 0;
}
else {//如果货车和客车都没有了停止
return;
}
}
}
int main() {
InitQueue(q1);
InitQueue(q2);
InitQueue(q);
EnQueue(q1, 1);
EnQueue(q1, 2);
EnQueue(q1, 3);
EnQueue(q1, 4);
EnQueue(q1, 5);
EnQueue(q1, 6);
EnQueue(q1, 7);
EnQueue(q1, 8);
EnQueue(q2, 9);
Manager();
ElemType e;
DeQueue(q, e);
printf("e=%d\n", e);
DeQueue(q, e);
printf("e=%d\n", e);
DeQueue(q, e);
printf("e=%d\n", e);
DeQueue(q, e);
printf("e=%d\n", e);
DeQueue(q, e);
printf("e=%d\n", e);
DeQueue(q, e);
printf("e=%d\n", e);
DeQueue(q, e);
printf("e=%d\n", e);
DeQueue(q, e);
printf("e=%d\n", e);
}