队列的基本运算实现

2023-10-26

队列(queue

队列是一种先进先出(first in first outFIFO的线性表。它只允许在表的一端(队尾/rear)插入元素,而在另一端(队头/front)删除元素。插入操作称为入队或进队,删除操作称为出队或离队。队列示意图如下:


1、 顺序队

队列的顺序存储结构需要使用一个数组和两个整型变量来实现,数组用于存储队列中的所有元素,两个整型变量分别用于存储队头元素和队尾元素的下标位置,分别称为队头指针和队尾指针。

假定队列的元素个数不超过MaxSize,所有的元素的数据类型都是ElemType,则顺序队列类型SqQueue定义如下:

typedefstruct

{

         ElemType data[MaxSize];

         Int front,rear;

}SqQueue;

在顺序队列*q中,队空的条件是q->front==q->rear;队满的条件是q->rear==MaxSize-1;元素e入队的操作是先将队尾指针加1,然后将元素e放入队尾;出队操作是先将队头指针加1,然后取出队头处的元素;队尾指针总是指向当前队列中的队尾元素,而队头指针总是指向当前队列中队头元素的前一个位置。

顺序队的基本运算实现如下:

#include<stdio.h>
#include<stdlib.h>

#define MaxSize 20	//队列元素最大个数
typedef char ElemType;		//队列元素类型
typedef struct	//顺序队
{
	ElemType data[MaxSize];	//数据元素
	int front;	//对头指针
	int rear;	//队尾指针
}SqQueue;

void InitQueue(SqQueue *&q)	//初始化队列
{
	q=(SqQueue *)malloc(sizeof(SqQueue));
	q->front=q->rear=-1;
}

void DestoryQueue(SqQueue *&q)	//销毁队列
{
	free(q);
}

bool QueueEmpty(SqQueue *q)		//判断队列是否为空
{
	return (q->front==q->rear);
}

bool QueueFull(SqQueue *q)	//判断队列是否已满
{
	return (q->rear==MaxSize-1);
}

bool EnQueue(SqQueue *&q, ElemType e)	//入队(插入元素)
{
	if(q->rear==MaxSize-1)	//队列已满,不能再插入
		return false;
	q->rear++;
	q->data[q->rear]=e;
	return true;
}

bool DeQueue(SqQueue *&q, ElemType &e)	//出队(删除元素)
{
	if(q->front==q->rear)	//队列为空,无法删除
		return false;
	q->front++;
	e=q->data[q->front];
	return true;
}

int main()
{
	...;
	return 0;
}

2、 环形队列

将数组的前端和后端连接起来,形成环形的顺序表——环形队列。

环形队列的基本运算实现如下:

#include<stdio.h>
#include<stdlib.h>

#define MaxSize 10	//队列元素最大个数
typedef char ElemType;		//队列元素类型
typedef struct	//环形队列
{
	ElemType data[MaxSize];	//数据元素
	int front;	//对头指针
	int rear;	//队尾指针
}QuType;

void InitQueue(QuType *&qu)		//初始化队列
{
	qu=(QuType *)malloc(sizeof(QuType));
	qu->front=qu->rear=0;
}

void DestoryQueue(QuType *&qu)	//销毁队列
{
	free(qu);
}

bool QueueEmpty(QuType *&qu)	//判断队列是否为空
{
	return (qu->front==qu->rear);
}

bool QueueFull(QuType *&qu)		//判断队列是否已满
{
	return (qu->front==(qu->rear+1)%MaxSize);
}

bool EnQueue(QuType *&qu, ElemType e)	//入队
{
	if(qu->front==(qu->rear+1)%MaxSize)	//注意!
		return false;
	qu->rear=(qu->rear+1)%MaxSize;
	qu->data[qu->rear]=e;
	return true;
}

bool DeQueue(QuType *&qu, ElemType &e)	//出队
{
	if(qu->front==qu->rear)
		return false;
	qu->front=(qu->front+1)%MaxSize;
	e=qu->data[qu->front];
	return true;
}

int main()
{
	...;
	return 0;
}

3、 链队

队列的链式存储结构通过由结点构成的单链表实现,此时只允许在单链表的表头进行删除操作和在单链表的表尾进行插入操作,因此需要两个指针:队首指针front和队尾指针rear。用front指向队首结点,用rear指向队尾结点。用于存储队列的单链表成为链队。

链队(带头结点)中数据结点的类型QNode定义如下:

typedefstruct qnode

{

         ElemType data;

         struct qnode *next;

}QNode;         //链队数据结点类型定义

链队结点的类型LinkQueue定义如下:

typedefstruct

{

         QNode *front;

         QNode *rear;

}LinkQueue;  //链队类型定义        

链队的基本运算实现如下:

#include<stdio.h>
#include<stdlib.h>

typedef char ElemType;
typedef struct qNode
{
	ElemType data;
	struct qNode *next;
}QNode;	//数据结点
typedef struct 
{
	QNode *front;	//队头指针
	QNode *rear;	//队尾指针
}LinkQueue;	//链队结点

void InitQueue(LinkQueue *&q)	//初始化链队
{
	QNode *p=(QNode *)malloc(sizeof(QNode));	//创建头结点
	if(!p)
	{
		printf("内存分配失败\n");
		exit(1);
	}
	p->next=NULL;
	q=(LinkQueue *)malloc(sizeof(LinkQueue));	//分配链队结点空间
	if(!q)
	{
		printf("内存分配失败\n");
		exit(1);
	}
	q->front=q->rear=p;
}

void DestoryQueue(LinkQueue *&q)	//销毁链队
{
	QNode *p;
	while(q->front!=NULL)
	{
		p=q->front;
		q->front=p->next;
	}
	free(p);
}

bool QueueEmpty(LinkQueue *q)	//判断队列是否为空
{
	return (q->front->next==NULL);
}

void EnQueue(LinkQueue *&q, ElemType e)	//入队
{	
	QNode *p;
	p=(QNode *)malloc(sizeof(QNode));	//创建新结点
	if(!p)
	{
		printf("内存分配失败!\n");
		exit(1);
	}
	p->data=e;
	p->next=NULL;
	q->rear->next=p;
	q->rear=p;
}

bool DeQueue(LinkQueue *&q, ElemType &e)	//出队
{	
	QNode *p;
	if(q->front->next==NULL)	//队列为空,操作无效
		return false;
	p=q->front->next;
	e=p->data;
	q->front->next=p->next;
	if(p->next==NULL)	//删除最后一个结点后,将尾指针指向头结点
		q->rear=q->front;
	free(p);
	return true;
}

int main()
{
	...;
	return 0;
}

几个注意点:

1、顺序队和环形队列的队空条件均是q->front==q->rear;顺序队的队满条件是p->rear==MaxSize-1,而环形队列的队满条件是q->front==(q->rear+1)%MaxSize;

2、顺序队和环形队列初始化的不同,导致最后存储空间上的元素不一样。顺序队的初始化:q->front=q->rear=-1,所以元素从q->data[0]开始存储;而环形队列的初始化:q->front=q->rear=0,所以元素从q->data[1]开始存储,q->data[0]空闲;

3、顺序队列满足队满条件时可能是假溢出(如p->rear==MaxSize-1,此时即使出队几个数据仍然满足了队满条件,但已经腾出了若干个空间,此时就是假溢出),而环形队列满足队满条件就是没有多余的存储空间了;

4、顺序队中的元素个数是rear-front,环形队列中的元素个数是(rear-front+MaxSize)%MaxSize;

5、链队的初始化,创建头结点的同时,为链队结点分配内存空间;

6、出队时,当删除最后一个结点后,尾指针也随之释放,所以应该将尾指针重新赋值,指向头结点。

 2014年7月29日星期二




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

队列的基本运算实现 的相关文章

随机推荐

  • 程序性能分析及性能测试

    这里所说的程序是指对外提供tcp ip交互协议的服务性程序 网络程序性能分析很重要 比如随着网络请求流量越来越大 我们需要知道已部署的服务能不能满足需求 这里采用对网络服务程序进行建模的方法分析影响程序性能的各要素 并计算相关性能值 它不够
  • odoo权限规则

    文章目录 odoo权限的层级划分 模型 表 级访问权限管理 记录规则权限 1 创建用户 2 新建权限组 用户组 3 创建记录规则 record rule 字段权限控制 菜单级权限管理 工作流权限管理 隐藏的常用技巧 Eval odoo权限的
  • 编译linux内核(二)

    编译linux内核 1 准备工作 1 1 下载内核文件 1 2 环境准备 1 3 内核命名规则 1 4 内核镜像 1 4 ELF 2 编译内核 2 1 升级gcc 2 2 make menuconfig其他报错 2 3 配置选项 2 4 编
  • MySQL数据库中的索引(含SQL语句)

    文章目录 为什么要用索引 索引是什么 索引的原理 优点 缺点 创建索引的原则 什么情况下需要索引 什么情况下不需要索引 索引的分类 主键索引 单值索引 唯一索引 组合索引 复合索引 全文索引 仅在MySQL8之后有 查找索引 索引的数据结构
  • cmd和dos的区别(汇总)

    你在windows操作系统里进的DOS 即输入 CMD 进命令提示符 不是纯DOS 只是为方便某些需求而建立的 而纯DOS本身就是一种操作系统 两者的区别 比如你可以在纯DOS下删除你的 windows系统 但在你所说的 命令提示符 里却不
  • Mac 让 iTerm2 记住用户名密码 expect 脚本

    刚刚用iTerm2的时候 总是要一遍遍的敲用户名 密码 我在想 能不能像Windows的软件一样 可以直接让软件记住 然后只要点击一下 就直接ssh到远程服务器上面去了 之后经过搜索 可以用expect脚本实现 usr bin expect
  • SSM学生作业管理系统-计算机毕设 附源码20912

    SSM学生作业管理系统 摘 要 随着科学技术的飞速发展 各行各业都在努力与现代先进技术接轨 通过科技手段提高自身的优势 对于学生作业管理系统当然也不能排除在外 随着网络技术的不断成熟 带动了学生作业管理系统 它彻底改变了过去传统的管理方式
  • 【webpack5】高级优化

    介绍 本章节主要介绍 Webpack 高级配置 所谓高级配置其实就是进行 Webpack 优化 让我们代码在编译 运行时性能更好 我们会从以下角度来进行优化 提升开发体验 提升打包构建速度 减少代码体积 优化代码运行性能 提升开发体验 So
  • 安装Node.js后,查看npm版本时出现警告

    执行命令 npm v 时 npm WARN config global global local are deprecated Use location global instead 修改安装的 node js 的文件架下的 npm cmd
  • sublime 自动补全

    preferences gt settings 在右边窗口最后位置添加 auto complete true 出现打过的单词 auto match enabled true 自动补全括号或引号
  • 【满分】【华为OD机试真题2023 JS】开心消消乐

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 开心消消乐 知识点编程基础深搜广搜 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 给定一个N行M列的二维矩阵 矩阵中每个位置的数字取值为0或1 矩阵示例如 1
  • 《思考的艺术》——书评与思维导图

    抽空读了下这本书 先说说整体感觉 内容基本满意 书的布局非常不喜欢 先吐槽吧 目录太过宽泛 给人造成 只见树木不见林 的感觉 目前只列出了各章节的标题在目录中 但每个章节包含很多的小标题 各标题的字体 大小都一样 很难区分逻辑 层次关系 如
  • 银行业务系统数据库设计与实现

    银行业务系统数据库的设计与实现 1 创建数据库银行业务系统数据库 bankDB Drop database if EXISTS bankDB 删除bindDB数据库 即使没有数据库也不报错 CREATE database bankDB 创建
  • preprocessing.LabelEncoder()使用

    preprocessing LabelEncoder 使用 e g 1 from sklearn import preprocessing le preprocessing LabelEncoder arr gf 1 2 3 wom wom
  • 基于Zigbee的智能路灯控制系统的Qt操作界面

    本项目已经用于参加过比赛 在加之本人确实有点忙 所以拖到现在才发 这里只详细说明关于Qt控制界面的相关功能说明 本来是19年写的 代码量有点大 具体的地方 我自己都可能有点遗忘了 不过还是发出来供大家参考使用 因为当初时间紧迫可能代码格式不
  • 华为OD题目: 投篮大赛

    package com darling boot order od od9 import com sun org apache bcel internal generic IF ACMPEQ import java util 投篮大赛 知识
  • Android Studio 创建项目不自动生成BuildConfig文件

    今天在AS上新建项目发现找不到BuildConfig文件 怎么clear都不行 通过多方面查找发现原来gradle版本不同造成的 Gradle 8 0默认不生成 BuildConfig 文件 如上图 8 0版本是没有source文件夹 上图
  • 软件测试-网站测试

    按照以下六个顺序进行测试 1 黑盒测试 在测试网站时 首先应该建立状态表 第5章 把每个网页当作不同的状态 超级链接当作状态之间的连接线 完整的状态图有利于对整个任务更好地进行审视 查找具体网页缺陷的思路 文本 把网页文本当作文档对待 根据
  • 无线基本概述(二)

    1 一些参数 MAC MAC 即Medium MediaAccess Control 介质访问控制 是数据链路层的一部分 MAC地址是烧录在NetworkInterfaceCard 即网卡 简称NIC 里的 它也叫硬件地址 是由48位 即b
  • 队列的基本运算实现

    队列 queue 队列是一种先进先出 first in first out FIFO 的线性表 它只允许在表的一端 队尾 rear 插入元素 而在另一端 队头 front 删除元素 插入操作称为入队或进队 删除操作称为出队或离队 队列示意图