当前位置: 首页 > article >正文

考研篇——数据结构王道3.2.2_队列的顺序实现

目录

  • 1.实现方式说明
  • 2.代码实现
    • 2.1
      • 2.1.1 代码1
      • 2.1.2 代码2
      • 2.1.3 代码3
    • 2.2
      • 2.2.1 代码4
      • 2.2.5 代码5
      • 2.2.6 代码6
  • 总结

1.实现方式说明

多在选择题中考察

队尾指针(rear)有两种指向方式:

  • 队尾指针指向队尾元素的位置,
  • 队尾指针指向队尾元素的下一个位置。

区分队空与队满:

  1. 牺牲一个存储空间,利用队头元素和队尾元素的相对位置来区分队空与队满。
  2. 增加一个变量size记录队列元素个数
  3. 增加一个变量tag记录操作是删除(tag为0)还是插入(tag为1),插入后rear(队尾)=front是队满,删除后rear=front是队空。

所以队列的实现一共有六种情况
在这里插入图片描述
书写代码注意操作实现的前提条件,也就是逻辑问题:

  1. 查、删的前提是队列非空,要进行判断;
  2. 插入的前提是队列不满,要进行判断。

静态数组实现的队列是循环队列,为了循环利用空间,rear的下一个元素为(rear+1)%MaxSize.

2.代码实现

2.1

2.1.1 代码1

C++静态数组实现rear(队尾指针)指向队尾元素的下一个元素,且牺牲一个存储空间来区分队满和队空的判断。
这种情况下队列的长度为(rear+MaxSize-front)%MaxSize.

#include <stdio.h>
#include <assert.h>
#define MaxSize 10
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)
{
	if (Q.rear == Q.front)
		return true;
	else
		return false;
}
bool EnQueue(SqQueue& Q,ElemType x) {
	if ((Q.rear + 1) % MaxSize == Q.front)
		return false;
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;
	return true;
}
bool DeQueue(SqQueue& Q, ElemType& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	return true;
}
bool GetHead(SqQueue Q, ElemType& x)
{
	//assert(!QueueEmpty(Q));
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	return true;
}
void testQueue()
{
	SqQueue Q;
	InitQueue(Q);
	//printf("%d\n",QueueEmpty(Q));
	EnQueue(Q, 5);
	int x = 0;
	DeQueue(Q, x);
	GetHead(Q, x);
	printf("%d\n",x);
}
int main() {
	testQueue();
	return 0;
}

后续代码与代码1相同的部分省略

2.1.2 代码2

C++静态数组实现rear(队尾指针)指向队尾元素的下一个元素,且增加一个变量size记录队列长度来区分队满和队空的判断。

//队尾指针指向队尾元素
//引入size变量来记录队列元素个数
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)
{
	if (Q.size==0)
		return true;
	else
		return false;
}
bool EnQueue(SqQueue& Q, ElemType x) {
	if (Q.size==MaxSize)//队满的判断
		return false;
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;
	Q.size++;
	return true;
}
bool DeQueue(SqQueue& Q, ElemType& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	Q.size--;
	return true;
}

2.1.3 代码3

C++静态数组实现rear(队尾指针)指向队尾元素的下一个元素,且增加一个变量tag来记录判断前队列的上一步操作是入队还是出队来区分队满和队空的判断。

//队尾指针指向队尾元素
//引入tag变量来记录队列元素个数,元素入队tag为1,出队tag为1
typedef struct {
	ElemType data[MaxSize];
	int front, rear;
	int tag;
}SqQueue;
void InitQueue(SqQueue& Q)
{
	Q.rear = Q.front = 0;
	Q.tag = 0;
}
bool QueueEmpty(SqQueue Q)
{
	if (Q.rear == Q.front&&Q.tag==0)
		return true;
	else
		return false;
}
bool EnQueue(SqQueue& Q, ElemType x) {
	if (Q.rear == Q.front && Q.tag == 1)
		return false;
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;
	Q.tag = 1;
	return true;
}
bool DeQueue(SqQueue& Q, ElemType& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	Q.tag = 0;
	return true;
}

其实我们遇到的问题是,Q.rear==Q.front可以表示队空和队满两种状态,那么我们考虑怎么将二者分开呢?1.牺牲一个存储单元,将队满对队空的判断条件区别开;2.增加size变量;3.增加tag变量,只有入队之后才有可能队满,出队之后才有可能队空。
三种情况的对比图如下:
在这里插入图片描述

2.2

2.2.1 代码4

C++静态数组实现rear(队尾指针)指向队尾元素,且牺牲一个存储空间来区分队满和队空的判断。

//队尾指针指向队尾元素下一个元素
//牺牲一个存储空间
void InitQueue(SqQueue& Q)
{
	Q.rear = -1;
	Q.front = 0;
}
bool QueueEmpty(SqQueue Q)
{
	if ((Q.rear + 1) % MaxSize == Q.front)
		return true;
	else
		return false;
}
bool EnQueue(SqQueue& Q, ElemType x) {
	if ((Q.rear + 2) % MaxSize == Q.front)
		return false;
	Q.rear = (Q.rear + 1) % MaxSize;
	Q.data[Q.rear] = x;
	return true;
}
bool DeQueue(SqQueue& Q, ElemType& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	return true;
}

2.2.5 代码5

C++静态数组实现rear(队尾指针)指向队尾元素,且增加一个变量size记录队列长度来区分队满和队空的判断。

typedef struct {
	ElemType data[MaxSize];
	int front, rear;
	int size;
}SqQueue;
void InitQueue(SqQueue& Q)
{
	Q.rear = -1;
	Q.front = 0;
	Q.size=0;
}
bool QueueEmpty(SqQueue Q)
{
	if (Q.size==0)
		return true;
	else
		return false;
}
bool EnQueue(SqQueue& Q, ElemType x) {
	if (Q.size==MaxSize)
		return false;
	Q.rear = (Q.rear + 1) % MaxSize;
	Q.data[Q.rear] = x;
	Q.size++;
	return true;
}
bool DeQueue(SqQueue& Q, ElemType& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	Q.size--;
	return true;
}

2.2.6 代码6

C++静态数组实现rear(队尾指针)指向队尾元素的下一个元素,且增加一个变量tag来记录判断前队列的上一步操作是入队还是出队来区分队满和队空的判断。

typedef struct {
	ElemType data[MaxSize];
	int front, rear;
	int tag;
}SqQueue;
void InitQueue(SqQueue& Q)
{
	Q.rear = -1;
	Q.front = 0;
	Q.tag=0;
}
bool QueueEmpty(SqQueue Q)
{
	if (Q.tag==0)
		return true;
	else
		return false;
}
bool EnQueue(SqQueue& Q, ElemType x) {
	if ((Q.rear + 1) % MaxSize == Q.front &&Q.tag==0)
		return false;
	Q.rear = (Q.rear + 1) % MaxSize;
	Q.data[Q.rear] = x;
	Q.tag=1;
	return true;
}
bool DeQueue(SqQueue& Q, ElemType& x)
{
	if (QueueEmpty(Q))
		return false;
	x = Q.data[Q.front];
	Q.front = (Q.front + 1) % MaxSize;
	Q.tag=0;
	return true;
}

总结

以上部分为王道课件代码,部分为自写代码,有问题欢迎交流。
注:王道本身图画得很形象,此处不再做图,有兴趣的伙伴可以去看一下王道该章节的内容。


http://www.kler.cn/news/365763.html

相关文章:

  • 01 springboot-整合日志(logback-config.xml)
  • vue3使用i18n做国际化多语言,实现常量跟随语言切换翻译
  • 基于docker 部署redis
  • 微信小程序中关闭默认的 `navigationBar`,并使用自定义的 `nav-bar` 组件
  • mac nwjs程序签名公证(其他mac程序也一样适用)
  • 【揭秘】图像算法工程师岗位如何进入?
  • 大一物联网要不要转专业,转不了该怎么办?
  • Scala的多态:定义,作用,实现手法
  • AUTOSAR从入门到精通-英飞凌GTM模块
  • Go语言生成UUID的利器:github.com/google/uuid
  • Node.js 路由
  • 文本预处理——构建词云
  • 【云效】阿里云云效:一站式DevOps平台介绍与使用教程(图文)附PPT
  • 2024 项目管理工具大变革:Jira 的替代者是谁?
  • 【数据分享】全国各省份农业-瓜果类面积(1993-2018年)
  • Python+Django+VUE 搭建深度学习训练界面 (持续ing)
  • CRLF、UTF-8这些编辑器右下角的选项的意思
  • STM32Lx GXHT3x SHT3x iic 驱动开发应用详解
  • 【Git】将本地代码提交到github仓库
  • 【Unity 安装教程】
  • Node.js 进阶:V8 垃圾回收机制全解析
  • ClickHouse与各种组件的关系
  • kotlin定时器和主线程定时器
  • Python的变量与数据类型——变量的定义
  • 今日头条躺赚流量:自动化新闻爬取和改写脚本
  • vue3 + VIte + TS 移动端 H5 项目屏幕适配,PC端响应式布局