c++数据结构:队列

队列是一种先进先出(FIFO)的线性表,只允许在表的一端进行插入、另一端进行删除。

 顺序队列:

数据类型定义如下:

 队列的总体功能的实现:

queue.h文件

const int MAX_Capacity = 100;//最大容量
template<class T>
class queue
{
private:
	T* _elem;//数据
	int _front;//队头
	int _rear; //队尾
public:
	queue()
	{
		_elem = new T[100];//开辟100个空间
		_front = 0;//队头初始为0
		_rear = 0;//队尾初始为0
	}
	~queue()
	{
		if (!empty())
		{
			delete[] _elem;
		}

	}
	bool empty();//判空
	int length();//队列长度
	T gethead();//获取队头元素
	void enqueue(T a);//插入元素
	void dequeue();//删除元素
};

 queue.cpp文件:

#include "queue.h"
template<class T>
bool queue<T>::empty()//判空
{
	if (_rear == _front)//当这两个位置相同时
	{
		return true;
	}
	else
		return false;
}
template<class T>
int queue<T>::length()//队列长度
{
	return _rear - fornt;
}
template<class T>
T queue<T>::gethead()//获取队头元素
{
	if (!empty())
	{
		return _elem[0];//返回队头元素
	}
	else
	{
		return;
	}
}
template<class T>
void queue<T>::enqueue(T a)//插入元素
{
	if (_rear == MAX_Capacity)
	{
		printf("已满无法插入\n");
		return;
	}
	_elem[_rear] = a;
	_rear++;
}
template<class T>
void queue<T>::dequeue()//删除元素
{
	//队头删除元素
	if (empty())return;//为空的话,结束
	for (int i = 0; i < _rear; i++)//把元素前移一格
	{
		_elem[i] = elem[i + 1];
	}
	_rear--;//队尾-1
}

在这里的删除操作为:

把队头元素删除,然后把后面的元素前移。

循环队列:

概念可看以下视频:

3.6 循环队列_哔哩哔哩_bilibili

 将 队列 存储空间的最后一个位置绕到第一个位置,形成逻辑上的环状空间,供队列循环使用。

通过取余%来限制下标

在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,也有front=rear。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件是front=rear,而队列判满的条件是front=(rear+1)%MaxSize

判空:front=rear

判满:(rear+1)%Maxsize=front

入队:rear=(rear+1)%Maxsize

出队:front=(front+1)%Maxsize

求队长:(rear-front+Maxsize)%Maxsiz

 代码的实现:

const int Max_size = 100;
template<class T>
class queue_C
{
private:
	T* _elem;//数据
	int _front;//队头
	int _rear;//队尾
public:
	queue_C()
	{
		_elem = new T[Max_size];
		_front = 0;
		_rea = 0;
	}
	queue_c()
	{
		if (_elem)
		{
			delete[] _elem;
		}
	}
	bool empty();//判空
	bool sentence_full();//判满
	int length();//队长
	void enqueue(T const a);//入队
	void dequeue();//出队
};

#include "queue_C.h"
template<class T>
bool queue_C<T>::empty()//判空
{
	if (_rear == _front)
	{
		return true;
	}
	return false;
}
template<class T>
bool queue_C<T>::sentence_full()//判满
{
	if ((_rear + 1) % Max_size == _front)return true;
	return false;
}
template<class T>
int queue_C<T>::length()//队长
{
	return (_rear - _front + Max_size) % Max_size;
}
template<class T>
void queue_C<T>::enqueue(T const a)//入队
{
	if (sentence_full())return;//队满无法入队
	_elem[_rear] = a;
	_rear = (_rear + 1) % Max_size;
}
template<class T>
void queue_C<T>::dequeue()//出队
{
	if (empty())return;//队空无法出队
	_front = (_front + 1) % Max_size;
}

链队列:

队列的链式存储是在链表的基础上,按照“先进先出”的原则操作数据元素。

  • 相比普通的队列,元素出队时无需移动大量元素,只需移动头指针。
  • 可动态分配空间,不需要预先分配大量存储空间。
  • 适合处理用户排队等待的情况。

链队列的节点结构:

template<class T>
class queue_L//队列节点
{
private:
	T _elem;
	queue_L<T>* next;
};

空链队列的表示:

class Queue//链队列
{
private:
	queue_L<T>* _front;//队头节点
	queue_L<T>* _rear;//队尾
public:
	Queue()
	{
		queue_L<T>* p1 = new queue_L<T>;//生成一个空节点
		p1->_elem = 0;
		p1->next = nullptr;
		_front = p1;//队头指向空节点
		_rear = p1;//队尾指向空节点
	}
	~Queue(){}
};

 插入的逻辑图:

void Queue<T>::enqueue(T const d)//插入
{
	queue_L<T>* p = new queue_L<T>;//生成一个新节点
	p->next = nullptr;
	p->_elem = d;
	_rear->next = p;//将队列和节点连接
	_rear = p;//队尾指针指向新节点
}

删除的逻辑图:

template<class T>
void Queue<T>::dequeue()//删除队尾元素
{
	if (_front==_rear)return;//队列为空的话,不执行
	queue_L<T>* p = new queue<T>;
	p = _front->next;//用一个新节点指向被删除节点
	_front->next = p->next;//第一个节点指向被删节点的下一个节点
	delete p;//删除该节点;
}

整体的代码:

template<class T>
class Queue;
template<class T>
class queue_L//队列节点
{
	friend class Queue<T>;//友元类
private:
	T _elem;
	queue_L<T>* next;
};
template<class T>
class Queue//链队列
{
private:
	queue_L<T>* _front;//队头节点
	queue_L<T>* _rear;//队尾
public:
	Queue()
	{
		queue_L<T>* p1 = new queue_L<T>;//生成一个空节点
		p1->_elem = 0;
		p1->next = nullptr;
		_front = p1;//队头指向空节点
		_rear = p1;//队尾指向空节点
	}
	~Queue()
	{
		while (!empty())//队列不为空,就一直删除节点
		{
			dequeue();
		}
		delete p1;
	}
	bool empty();//判空
	void enqueue(T const d);//插入
	void dequeue();//删除队尾元素
};
#include "queue_L.h"
template<class T>
bool Queue<T>::empty()//判空
{
	if (_rear == _front)return true;
	return false;
}
template<class T>
void Queue<T>::enqueue(T const d)//插入
{
	queue_L<T>* p = new queue_L<T>;//生成一个新节点
	p->next = nullptr;
	p->_elem = d;
	_rear->next = p;//将队列和节点连接
	_rear = p;//队尾指针指向新节点
}
template<class T>
void Queue<T>::dequeue()//删除队尾元素
{
	if (empty())return;//队列为空的话,不执行
	queue_L<T>* p = new queue<T>;
	p = _front->next;//用一个新节点指向被删除节点
	_front->next = p->next;//第一个节点指向被删节点的下一个节点
	delete p;//删除该节点;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值