【数据结构】浅谈C++实现队列

简言之,队列具有以下特点:

  1. 初始值front=rear=-1
  2. front指向第一个数据的前面,rear直接指向最后一个数据
  3. 判断队列为空的条件是front==rear
  4. 判断队列满的条件是rear==maxSize-1
  5. 有效数据个数为rear-front
  6. 入队时先增加rear,再在rear处插入数据
  7. 出队时先增加front,再在front处取出数据

在队尾添加元素,在队首删除元素(排队,先到先出)

循环队列

基本思路

数组+指针实现,需要指定队列长度。

前期准备:

1.需要两个指针:队首(front)、队尾(rear)指针

front永远指向队头元素前一位置,front之后才是第一结点

2.循环链接首尾

队列长度:Qsize

(rear+1)%Qsize==front

3.通过C++类实现功能封装

class CirQueue{
	public:
		CirQueue();
		~CirQueue();
		void add(int x); 	//入队 
		int chu();			//出队 
		int get();			//取队首元素 
		int empty();		//判空 
		void print(); 
	private:
		int front ,rear;			//front永远指向队头元素前一位置。front之后才是第一结点 
		int data[Qsize];   			//数组存储循环队列 
};

基本操作思路:

1.添加在队尾进行,rear后移之后加数据

2.出队在队首进行,front后移以使第一结点后移

注意:

1.队空:前、后指针相等.即:front==rear

2.队满:牺牲一个空间 .即:(rear+1)%Qsize==front

功能实现

构造函数
CirQueue::CirQueue(){
	front=rear=-1;		//front 指向队列元素前
} 
入队
void CirQueue::add(int x){
	//先判断队满:牺牲一个空间  
	if((rear+1)%Qsize==front) throw"队满" ;
	//在队尾加入元素
	rear= (rear+1)%Qsize;			
    //尾指针后移,在新位置插入元素 
	data[rear]=x;
}
出队
int CirQueue::chu(){
	//队首出队  
	if(front==rear) throw"队空!";
	front=(front+1)%Qsize;			//front最初指向队头元素前一位置。头指针后移,使得原来的的队首元素出队 
	return data[front]; 			
}
判空
int CirQueue::empty(){
	//队空条件:前、后指针相等 
	if(front==rear) return 1; 
		else return 0; 
}
取队首元素
int CirQueue::get(){
	if(front==rear) throw"队空!";
	return  data[(front+1)%Qsize];	//取队首元素 
}
遍历队列
void CirQueue::print(){
	cout<<"当前队列中的所有元素为:";
	for(int i=front+1;i<=rear;i++) cout<<data[i]<<" ";
	cout<<endl; 
}

完整代码

#include<iostream>
using namespace std;
const int Qsize=10;
class CirQueue{
	public:
		CirQueue();
		~CirQueue();
		void add(int x); 	//入队 
		int chu();			//出队 
		int get();			//取队首元素 
		int empty();		//判空 
		void print(); 
	private:
		int front ,rear;			//front永远指向队头元素前一位置。front之后才是第一结点 
		int data[Qsize];   			//数组存储循环队列 
};
CirQueue::CirQueue(){
	front=rear=-1;					//front 指向队头元素前一位置。
} 
CirQueue::~CirQueue(){}
void CirQueue::add(int x){
	//先判断队满:牺牲一个空间  
	if((rear+1)%Qsize==front) throw"队满" ;
	//在队尾加入元素
	rear= (rear+1)%Qsize;			//尾指针后移,在新位置插入元素 
	data[rear]=x;
}
int CirQueue::chu(){
	//队首出队  
	if(front==rear) throw"队空!";
	front=(front+1)%Qsize;			//front最初指向队头元素前一位置。头指针后移,使得原来的的队首元素出队 
	return data[front]; 			
}
int CirQueue::empty(){
	//队空条件:前、后指针相等 
	if(front==rear) return 1; 
		else return 0; 	
}
int CirQueue::get(){
	if(front==rear) throw"队空!";
	return  data[(front+1)%Qsize];	//取队首元素 
}
void CirQueue::print(){
	cout<<"当前队列中的所有元素为:";
	for(int i=front+1;i<=rear;i++) cout<<data[i]<<" ";
	cout<<endl; 
}

int main(){
	int x;
	CirQueue C;
	if(C.empty()) cout<<"队列空!"<<endl; 
	cout<<"入队操作!\n";
	C.add(5);
	C.add(8);	
	C.print();
	cout<<"当前队列队首元素为:"<<C.get()<<endl;
 
 	cout<<"-----------------"<<endl;
 	//尝试让元素出队
 	cout<<"元素出队!\n"; 
 	int  t=C.chu();
	cout<<"出队的是:"<<t<<endl;
	
	//验证出队效果 
	cout<<"当前队列队首元素为:"<<C.get()<<endl;
	C.print(); 
	return 0;
}

链队列

1.front永远指向队头元素前一位置,front之后才是第一结点

2.判断条件与循环对相同

队空:前、后指针相等.即:front==rear

类的声明

class LinkQueue
{
public:	
LinkQueue( ); 		//构造函数,初始化空链队列
~LinkQueue( ); 		//析构函数,释放链队列各结点的存储空间
void EnQueue(int x); 		//入队操作
DataType DeQueue( ); 		//队首元素出队
DataType GetQueue( ); 		//取链队列的队头元素
int Empty( ); 				//判空
private:
Node *front, *rear; 
    			//队头和队尾指针,分别指向头结点和队尾结点
};

功能实现

构造

队头指针和队尾指针都均指向头结点s

int :: LinkQueue( )
{
Node *s = nullptr;
s = new Node; s->next = nullptr; //创建头结点s
front = rear = s; 		//队头指针和队尾指针都指向头结点s
}
入队

链表实现存储,无需判断队满

void LinkQueue :: EnQueue(int x)
{
Node *s = nullptr;
s = new Node; 				//辅助结点s
s->data = x; s->next = nullptr;
rear->next = s; rear = s; 	//将结点s插入队尾
}
出队

需要判断队空: rear == front

int LinkQueue :: DeQueue( )
{
int x;
Node *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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值