队列

循环队列

#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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Baal Austin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值