数据结构-队列

 

目录

 队列的概述

 队列的顺序存储结构

 部分算法分析

 循环队列的表示和实现

 global.h 

 LoopQueue.h

 LoopQueueTest.cpp

 运行结果


队列的概述

  • 队列是一种重要的线性结构,同栈一样,属于一种操作受限的线性表
  • 队列(queue),只允许在表的一端进行插入操作,而在另一端进行删除操作
  • 队列允许插入的一端叫做队尾(rear),允许删除的一端叫做队头(front)
  • 队列元素遵循先进先出,即最先进入队列的元素最先出队列  

 

 队列的顺序存储结构

  •  开辟一组地址连续的存储单元依次存放从队列头到队尾的元素
  • 设有两个指针(front和rear),当front = rear 时表示队列为空
  • 队列插入新的元素时,队尾指针(rear)增1,始终指向队列尾元素的下一位置(非空队列)
  • 队列删除元素时,队头指针(front)增1,始终指向队列的头元素(非空队列) 

 顺序队列在不断进行插入、删除操作后,会导致队头(front)和队尾(rear)指针的不断增加,最终导致队列中虽然仍有空间进行元素的插入,但无法执行该操作(空间的假溢出)

 

 当出现假溢出的情况时,使用循环队列解决假溢出的情况,让队尾指针直接指向开辟空间的第一块区域,即如下图所示

 

 

 使用循环队列的方法,可以将其想象成开辟了一个环形连续空间(并不存在环形空间,实际仍是线形的连续空间)

 

 循环队列解决了假溢出的问题,但新的问题又出现了,此时 front = rear 既可以表示队列已满,又可以表示队列为空 

 两种解决方式: 其一是另设一个标识位以区别队列是空还是满,其二是少用一个元素空间,规定以队列头指针在队列尾指针的下一位置上,作为满队列状态,即如图所示

 


 部分算法分析

  • 循环队列的定义
typedef struct {
	//初始化的动态分配存储空间
	QElemType* base;
	//头指针,若队列不为空,指向队列头元素
	int front;
	//尾指针,若队列不为空,指向队列尾元素的下一个位置
	int rear;
}LoopQueue;

队头指针(front)以及队尾指针(rear)类型设置为 int 型,因为开辟的空间是连续型的一块空间,相当于数组,所以只需要对这块空间的索引进行相关操作即可

  •  元素入队列操作
//从队尾插入元素至队列中(入队列)
Status InsertLoopQueue(LoopQueue& Q, QElemType data) {
	//判断队列是否已满
	if ((Q.rear + 1) % MAX_QSIZE == Q.front) {
		cout << "循环队列已满,入队列操作失败" << endl;
		return ERROR;
	}
	Q.base[Q.rear] = data;
	Q.rear = (Q.rear + 1) % MAX_QSIZE;
	return OK;
}

 队尾指针(rear)始终指向队列最后插入的元素的后一个位置,之后让队尾指针增1,当rear的值为队列最大存储容量值 - 1时(即 MAX_QSIZE - 1 ),再进行入队列操作时会出现假溢出现象

 让队尾指针增1后再对队列最大存储容量值取模(即(Q.rear + 1) % MAX_QSIZE),rear的值重新从索引0开始

 举个例子,如图

 

 当元素a7入队列时,rear的值由7 + 1等于8,此时对队列最大容量值(MAX_QSIZE)取模,rear = 0,解决了假溢出的问题


 循环队列的表示和实现

  • global.h
  • LoopQueue.h
  • LoopQueueTest.cpp

global.h 

相关头文件的引用,以及相应全局变量、常量的声明

#pragma once
 
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
 
using namespace std;
 
#define TRUE 1
 
#define FALSE 0
 
#define OK 1
 
#define ERROR 0
 
#define INFEASIBLE -1
 
#define EQ(a,b) ((a) == (b))
 
#define LT(a,b) ((a) < (b))
 
#define LQ(a,b) ((a) <= (b))
 
#define MT(a,b) ((a) > (b))
 
#define MQ(a,b) ((a) >= (b))
 
typedef int Status;

LoopQueue.h

循环队列的定义以及循环队列的相关操作算法的实现

#pragma once
#include"global.h"
 
#define QElemType int 
#define MAX_QSIZE 100
 
typedef struct {
	//初始化的动态分配存储空间
	QElemType* base;
	//头指针,若队列不为空,指向队列头元素
	int front;
	//尾指针,若队列不为空,指向队列尾元素的下一个位置
	int rear;
}LoopQueue;
 
//循环队列的初始化(构造一个空队列)
Status InitLoopQueue(LoopQueue& Q) {
	Q.base = (QElemType*)malloc(MAX_QSIZE * sizeof(QElemType));
	//判断空间分配是否成功
	if (!Q.base)
		return ERROR;
	//将头指针与尾指针相等
	Q.front = Q.rear = 0;
	return OK;
}
 
//返回循环队列中已有元素的个数
int QueueLength(LoopQueue Q) {
	return (Q.rear - Q.front + MAX_QSIZE) % MAX_QSIZE;
}
 
//从队尾插入元素至队列中(入队列)
Status InsertLoopQueue(LoopQueue& Q, QElemType data) {
	//判断队列是否已满
	if ((Q.rear + 1) % MAX_QSIZE == Q.front) {
		cout << "循环队列已满,入队列操作失败" << endl;
		return ERROR;
	}
	Q.base[Q.rear] = data;
	Q.rear = (Q.rear + 1) % MAX_QSIZE;
	return OK;
}
 
//将队列的头元素删除(出队列)
Status DeleteLoopQueue(LoopQueue& Q, QElemType& data) {
	//判断队列是否尾空
	if (Q.front == Q.rear) {
		cout << "该队列为空队列,出队列操作失败" << endl;
		return ERROR;
	}
    data = Q.base[Q.front];
	Q.front = (Q.front + 1) % MAX_QSIZE;
	return OK;
}
 
//循环队列的赋值操作初始化
void InitLoopQueueData(LoopQueue& Q) {
	cout << "循环队列赋值初始化(赋值不超过" << MAX_QSIZE - 1 << "个元素)" << endl;
	cout << "输入插入循环队列元素的个数:" << endl;
	int nums = 0;
	cin >> nums;
	cout << "请输入" << nums << "个元素:" << endl;
	QElemType data = 0;
	for (int i = 0; i < nums; i++) {
		cin >> data;
		Q.base[Q.rear] = data;
		Q.rear = (Q.rear + 1) % MAX_QSIZE;
	}
	cout << "循环队列初始化成功" << endl;
}
 
//循环队列的遍历操作
void ShowLoopQueue(LoopQueue Q) {
	cout << "队列中的元素有:" << endl;
	while (Q.front != Q.rear) {
		cout << Q.base[Q.front] << " ";
		Q.front = (Q.front + 1) % MAX_QSIZE;
	}
	cout << endl;
}

LoopQueueTest.cpp

#include"LoopQueue.h"
 
int main() {
	LoopQueue queue;
	InitLoopQueue(queue);
	InitLoopQueueData(queue);
	ShowLoopQueue(queue);
	int length = QueueLength(queue);
	cout << "循环队列中的元素个数有:" << length << endl;
	cout << "---入队列操作---,输入数据:" << endl;
	QElemType data;
	cin >> data;
	InsertLoopQueue(queue, data);
	ShowLoopQueue(queue, data);
	cout << "---出队列操作---" << endl;
	DeleteLoopQueue(queue);
	ShowLoopQueue(queue);
}

 运行结果

 

循环队列赋值初始化(赋值不超过99个元素)
输入插入循环队列元素的个数:
7
请输入7个元素:
12 34 54 23 65 234 767
循环队列初始化成功
队列中的元素有:
12 34 54 23 65 234 767
循环队列中的元素个数有:7
---入队列操作---,输入数据:
345
队列中的元素有:
12 34 54 23 65 234 767 345
---出队列操作---
队列中的元素有:
34 54 23 65 234 767 345

F:\DataStructureForC++\Project\Debug\Project1.exe (process 14648) exited with code 0.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值