队列Queue

1、队列的定义

队列:(Queue)先进先出,后进后出,一端进行插入另一端进行删除。顺序队列就是循环队列,下面会说:
在这里插入图片描述

2、难点一

与栈相比而言,栈的入栈和出栈都是在栈顶进行操作时间复杂度都为O(1),但是如何队列的插入和删除的(入队和出队时间复杂度为O(1)?
在这里插入图片描述
将队列想象为循环的实际是不存在的,然后对其进行类似于魔方阵操作,即取模操作,来进行判满操作。

3、难点二

判空和判满条件都为:队头指针==队尾指针,如何让解决
解决方案1:再添加一个条件,即:判断有效节点个数,队头=队尾&&有效节点个数不为0,如下图所示:
在这里插入图片描述
**解决方案2:浪费最后一个空间,让其进行标记,当队尾向前跑一步之后,队头=队尾,如下:(队尾+1)%MAXSIZE=队头;**也有可能不在0相遇,下面只是举例。
在这里插入图片描述

4、难点三

两种情况:
在这里插入图片描述
有效节点个数=(队尾-队头+MAXSIZE)%MAXSIZE
前面的+MAXSIZE作用是为了防止队尾-队头结果出现负数,后面的%MAXSIZE是为了防止加多了。

5、结构体设计

typedef int ELEM_TYPE;
typedef struct Queue
{
	ELEM_TYPE* base;//用来保存malloc来的数组首地址
	int front;//保存队头下标
	int tail;//保存队尾下标
	//int length;用此来保存有效节点个数,更加方便
	/*用指针也可以,只不过用整型更方便一点*/
}queue,*Pqueue;

6、头文件

typedef int ELEM_TYPE;
typedef struct Queue
{
	ELEM_TYPE* base;//用来保存malloc来的数组首地址
	int front;//保存队头下标
	int tail;//保存队尾下标
	//int length;用此来保存有效节点个数,更加方便
	/*用指针也可以,只不过用整型更方便一点*/
}queue,*Pqueue;
//初始化
void Init_Queue(Pqueue pq);
//入队
bool push(Pqueue pq, ELEM_TYPE val);
//出队(如果出队的话,需要返回一下出队的值,因此要多加一个参数来保存,在主函数中可以来保存,下同)
bool Pop(Pqueue pq,ELEM_TYPE *rtval);
//获取队头元素值
bool Get_Top(Pqueue pq, ELEM_TYPE* rtval);
//获取队尾元素
bool Get_Tail(Pqueue pq, ELEM_TYPE* rtval);
//获取有效元素个数
int Get_length(Pqueue pq);
//判空
bool Is_Empty(Pqueue pq);
//判满
bool Is_Full(Pqueue pq);
//清空
void Clear(Pqueue pq);
//销毁
void Destory(Pqueue pq);
//打印
void Print(Pqueue pq);

7、函数实现

#if 1
#include"Queue.h"
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#define MAXSIZE 100
//初始化
void Init_Queue(Pqueue pq)
{
	assert(pq != NULL);
	pq->base = (ELEM_TYPE*)malloc(sizeof(ELEM_TYPE) * MAXSIZE);
	assert(pq->base != NULL);
	pq->front = pq->tail = 0;//让头尾都指向0下标
}
//入队(队尾入队)
bool push(Pqueue pq, ELEM_TYPE val)
{
	assert(pq != NULL);
	if (Is_Full(pq))
	{
		return false;
	}
	pq->base[pq->tail] = val;
	pq->tail = (pq->tail + 1) % MAXSIZE;//目的是将最后一个空间保留下来,防止越界,同时做到最后一个空间被浪费
	return true;
}
//出队(如果出队的话,需要返回一下出队的值,因此要多加一个参数来保存,在主函数中可以来保存,下同)
bool Pop(Pqueue pq, ELEM_TYPE* rtval)
{
	assert(pq != NULL);
	if (Is_Empty(pq))
	{
		return false;
	}
	*rtval = pq->base[pq->front];
	pq->front = (pq->front + 1) % MAXSIZE;//同上防止越界
	return true;
}
//获取队头元素值
bool Get_Top(Pqueue pq, ELEM_TYPE* rtval)
{
	assert(pq != NULL);
	if (Is_Empty(pq))
	{
		return false;
	}
	*rtval = pq->base[pq->front];
	return true;
}
//获取队尾元素
bool Get_Tail(Pqueue pq, ELEM_TYPE* rtval)
{
	assert(pq != NULL);
	if (Is_Empty(pq))
	{
		return false;
	}
	*rtval = pq->base[pq->tail];
	return true;
}
//获取有效元素个数
int Get_length(Pqueue pq)
{
	assert(pq != NULL);
	return ((pq->tail - pq->front + MAXSIZE) % MAXSIZE);
}
//判空
bool Is_Empty(Pqueue pq)
{
	assert(pq != NULL);
	if (pq->front == pq->tail)
	{
		return true;
	}
	return false;
}
//判满
bool Is_Full(Pqueue pq)
{
	assert(pq != NULL);
	if ((pq->tail+ 1) % MAXSIZE == pq->front)
	{
		return true;
	}
	return false;
}
//清空
void Clear(Pqueue pq)
{
	assert(pq != NULL);
	pq->front = pq->front = 0;
}
//销毁
void Destory(Pqueue pq)
{
	assert(pq != NULL);
	Clear(pq);
	free(pq);
	pq = NULL;
}
//打印
void Print(Pqueue pq)
{
	assert(pq != NULL);
	for (int i = pq->front; i != pq->tail; i=(i+1)%MAXSIZE)
	{
		printf("%d ", pq->base[i]);
	}
	printf("\n");
}
int main()
{
	struct Queue x = {};
	Pqueue pq = &x;
	Init_Queue(pq);
	for (int i = 0; i < 99; i++)//最后一个位置不能放数据
	{
		push(pq, i);
	}
	Print(pq);
	printf("队列是否已满%d ", Is_Full(pq));
	int rtval;
	for (int i = 0; i < 99; i++)//最后一个位置不能放数据
	{
		Pop(pq, &rtval);
		printf("%d ", rtval);
	}
}
#endif

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值