数据结构(C++)_3-2队列

基本概念

1.只允许在一端进行插入操作,在另一端进行删除操作的线性表;
2.队尾:允许插入(入队、进队)的一端;
3.队头:允许删除(出队)的一端;
4.特性:先进先出
5.例子:银行排队、键盘缓冲区、操作系统的作业调度

01顺序队列

1.设置队头、队尾变量 rear 、front;
2.入队rear+1、出队rear-1;
3.约定:front指向队头元素的前一个位置,rear指向队尾元素的位置;

02循环队列

1.假溢出:队列向数组高端移动,元素插入到数组下标的最大位置后,数组低端还有空闲空间;
2.解决方案:头尾相接的循环结构;
3.操作语句:rear = (rear + 1)%QueueSize;
4.队空:front = rear;
5.队满:(rear + 1) % QueueSize = front;(浪费一个数组元素空间;
实现:

#include<iostream>
using namespace std;
const int queue_Size = 100;
template <typename DataType>
class CirQueue
{
public:
	 CirQueue();			//循环队列构造函数
 	~CirQueue();			 //循环队列析构函数
 	void EnQueue(DataType x); 	//入队操作
 	DataType DeQueue();		//出队操作
 	DataType GetHead(); 		//取队头元素
 	int IsEmpty(); 			//判空操作
 private:
 	DataType data[queue_Size];
 	int rear, front;

具体实现:
(1)构造函数:将rear和front同时指向数组的某一位置(一般为高端);
(2)析构函数:无需
(3)入队操作:判断队满情况,rear循环意义上加1后插入数据

template <typename DataType>
void CirQueue<DataType>::EnQueue(DataType x)
{
 	if ((rear + 1) % queue_Size == front) throw"上溢";
	 rear = (rear + 1) % queue_Size;
 	data[rear] = x;
}

(4)出队操作:判断队空情况,front循环意义上加1,读取返回

template <typename DataType>
DataType CirQueue<DataType>::DeQueue()
{
 	if (rear == front)throw"下溢";
 	front = (front + 1) % queue_Size;
 	return data[front];
}

(5)取队头元素:判断是否为队空,否则返回结果

template <typename DataType>
DataType CirQueue<DataType>::GetHead()
{
 	if (rear == front)throw"下溢";
 	return data[(front + 1) % queue_Size];   //注意不改变front 指针
}

(6)判空操作:front 是否等于 rear;

03链队列

1.加头结点:空队列与非空队列一致;
2.设队头指针指向头结点,队尾指针指向终端结点;
实现:

#include <iostream>
using namespace std; 
template <typename DataType> 
struct Node  //结点
{  
  	DataType data;  
  	Node<DataType>* next; 
}; 
template<typename DataType>
class LinkQueue
{
public:
	 LinkQueue();					//链队列构造函数	 
 	~LinkQueue();					//链队列析构函数
 	void EnQueue(DataType x);		//入栈操作
 	DataType DeQueue();			//出栈操作
 	DataType GetHead();			//取队头元素
	 int IsEmpty();					 //判空操作
 private:
 	Node<DataType>* front, * rear;
 }

(1)构造函数:申请头结点,队头指针与队尾指针均指向头结点

template<typename DataType>
LinkQueue<DataType>::LinkQueue()
{
	 Node<DataType>* first = nullptr;
 	first = new Node<DataType>;
 	first->next = nullptr;
 	rear = front = first;
}

(2)析构函数

template<typename DataType>
LinkQueue<DataType>::~LinkQueue()
{
 	Node<DataType>* p = front->next;
 	while (front->next != nullptr)
 	{
  		front->next = p->next;
  		delete p;
  		p = front->next;
 	}
}

(3)入队操作

template<typename DataType>
void LinkQueue<DataType>::EnQueue(DataType x)
{
 	Node<DataType>* add;
 	add = new Node<DataType>;		//申请插入结点
 	add->data = x;
 	add->next = nullptr;
 	rear->next = add;
 	rear = add;
}

(4)出队操作:注意队列长度等于1的情况

template<typename DataType>
DataType LinkQueue<DataType>::DeQueue()
{ 
 	DataType x;
 	Node<DataType>* p = nullptr;
 	if (rear == front)throw "下溢";
	p = front->next;
 	x = p->data;
 	front->next = p->next;
 	if (p->next == nullptr)
  		rear = front;
 	delete p;
 	return x;
}

(5)取队头元素:返回第一个元素结点的数据域,即:front->next->data;
(6)判空操作:front是否等于rear;

循环队列与链队列比较

1.时间复杂度均为O(1);
2.循环队列需事先固定长度,有个数限制和浪费空间的问题;
3.链队列需要指针域,产生结构性开销;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值