循环队列和链队列的C++实现

队列可以分为顺序队列,循环队列以及链队列
顺序队列:
(1)如果队首元素删除之后,所有元素不移动,那么入队和出队操作的时间复杂度是O(1)
(2)如果队首元素删除之后,所有元素都要往前移动一位,那么入队的时间复杂度是O(1),出队的复杂度是O(n)
第一种做法在时间复杂度上比第二种做法要优越,但是可能会发生"假溢出",也就是数组的低端还有空闲位置,但是数组的高端却被插满了

循环队列:
循环队列则可以很好地解决"假溢出"这个问题,当数组高端满了之后,可以将队尾指针指向数组低端位置,这样就可以解决"假溢出"问题
其中,判断队满的条件是(rear+1)%queueSize==front,这样做虽然浪费了一个数组元素空间,但是减少了时间代价。判断队空的条件是rear=front
可以想出,判断队满的条件也可以是rear=front,但是如此做的话,会让判断队空和判断队满的条件重复,因此需要牺牲一个数组元素空间来判断队满

链队列:
链队列为了操作的方便,会设置一个头结点,然后用队头指针指向链队列的头结点,队尾指针指向终端结点
循环队列代码如下:

#include<iostream>
#include<string>
using namespace std;
const int queueSize = 10;
template<typename T>
class CirQueue
{
private:
	int front, rear;
	T data[queueSize];
public:
	CirQueue();
	void insertQueue(T x);//入队
	T exitQueue();//出队
	T getQueueHead();//得到队首元素
	bool empty();//判断是否为空
	void printQueue();//打印出队列里面的元素
};

template<typename T>
CirQueue<T>::CirQueue()
{
	front = rear = queueSize - 1;
}

template<typename T>
void CirQueue<T>::insertQueue(T x)
{
	if ((rear + 1) % queueSize == front)//插入元素前需要判断队列是否已经满了
	{
		throw exception("插入元素时发生了上溢");
	}
	rear = (rear + 1) % queueSize;
	data[rear] = x;
}

template<typename T>
T CirQueue<T>::exitQueue()
{
	if (front == rear)
	{
		throw exception("删除队首元素时发生了下溢");
	}
	front = (front + 1) % queueSize;
	return data[front];
}

template<typename T>
T CirQueue<T>::getQueueHead()
{
	if (front == rear)
	{
		throw exception("获取队首元素时发生了下溢");
	}
	int x = (front + 1) % queueSize;
	return data[x];
}

template<typename T>
bool CirQueue<T>::empty()
{
	if (front == rear)
	{
		return true;
	}
	return false;
}

template<typename T>
void CirQueue<T>::printQueue()
{
	if (front == rear)
	{
		throw exception("队列已空,无法打印元素");
	}
	front = (front + 1) % queueSize;
	while (front != rear)
	{
		cout << data[front] << endl;
		front++;
	}
	cout << data[front];
}
int main()
{
	CirQueue<int> cirQueue;
	try
	{
		cirQueue.insertQueue(1);
		cirQueue.insertQueue(10);
		cirQueue.insertQueue(100);
		cirQueue.insertQueue(1000);
		cout << "删除队首元素:" << cirQueue.exitQueue() << endl;
		cout << "得到队首元素:" << cirQueue.getQueueHead() << endl;
		cout << cirQueue.empty();
		cirQueue.printQueue();
	}
	catch (exception e)
	{
		cout << e.what() << endl;
	}
	return 0;
}

链队列的代码如下:

#include<iostream>
using namespace std;
template<typename T>
class Node
{
public:
	T data;
	Node<T>*next;
	Node() :next(nullptr) {};
};

template<typename T>
class LinkQueue
{
private:
	Node<T>*front, *rear;
public:
	LinkQueue();
	~LinkQueue();
	void insertQueue(T x);
	T deQueue();
	T getHead();
	void printQueue();
	bool empty();
};

template<typename T>
LinkQueue<T>::LinkQueue()//初始化链队列,将front指针和rear指针都指向头结点
{
	Node<T> *s = new Node<T>();
	front = rear = s;
}

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

template<typename T>
void LinkQueue<T>::insertQueue(T x)//链队列的插入
{
	Node<T>*s = new Node<T>();
	s->data = x;
	rear->next = s;
	rear = s;
}

template<typename T>
T LinkQueue<T>::deQueue()//链队列的删除
{
	if (rear == front)
	{
		throw exception("删除队首结点时发生了下溢");
	}
	Node<T>*p = new Node<T>();
	p = front->next;
	T x = p->data;
	front->next = p->next;
	if (front->next == nullptr)
	{
		rear = front;
	}
	delete p;
	return x;
}

template<typename T>
T LinkQueue<T>::getHead()
{
	if (front == rear)
	{
		throw exception("得到队首元素时发生了下溢");
	}
	return front->next->data;
}

template<typename T>
bool LinkQueue<T>::empty()//判断链队列是否为空
{
	if (front == rear)
	{
		return true;
	}
	return false;
}

template<typename T>
void LinkQueue<T>::printQueue()
{
	if (front == rear)
	{
		throw exception("队列为空,无法打印队列");
	}
	front = front->next;
	while (front != nullptr)
	{
		cout << front->data << endl;
		front = front->next;
	}
}

int main()
{
	LinkQueue<int> linkQueue;
	linkQueue.insertQueue(10);
	linkQueue.insertQueue(100);
	linkQueue.insertQueue(200);
	linkQueue.insertQueue(300);
	try
	{
		cout << "删除队首元素:" << linkQueue.deQueue() << endl;
		cout << "删除队首元素:" << linkQueue.deQueue() << endl;
		cout << "得到队首元素:" << linkQueue.getHead() << endl;
		cout << "删除队首元素:" << linkQueue.deQueue() << endl;
		cout << "删除队首元素:" << linkQueue.deQueue() << endl;
		cout << linkQueue.empty() << endl;
	}
	catch (exception e)
	{
		cout << e.what() << endl;
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值