队列概念
像堆栈一样,队列也是一种特殊的线性表。队列的插入和删除操作分别在线性表的两端进行,因此,队列是一个先进先出(first-in-first-out, FIFO)的线性表。
队列(quene)是一个线性表,其插入和删除操作分别在表的不同端进行。添加新元素的那一端被称为队尾( rear ),而删除元素的那一端被成为队首 ( front )。
图像解析 :
书中给了三种公式描述:
公式一:
对应的图:
公式二:
对应图:
公式三:
对应图:
由上面可以看出,公式3是最省空间的方法,也是常说的循环队列。
开始代码:
队列的数组形式:
/*
数组结构中的 队列 数组与链表描述
对应书中代码:数据结构算法与应用c++描述
程序编写:比卡丘不皮
编写时间:2020年7月16日 09:56:09
*/
#pragma once
#include <iostream>
#include "all_error.h"
using namespace std;
template<class T>
class Queue
{
public:
Queue(int MaxQueueSize = 10);
~Queue() { delete[] queue; }
bool IsEmpty() const { return front == rear; }
bool IsFull() const {
return (
((rear + 1) % MaxSize == front) ? 1 : 0);
}
T First() const; //返回队首元素
T Last() const; // 返回队尾元素
Queue<T>& Add(const T& x);
Queue<T>& Delete(T& x);
int Length() const;
void Input(istream &in) //输入一个队列
{
int size;
cout << "请输入队列的大小: ";
cin >> size;
cout << "请输入队列元素: " << endl;
for (int i = 0; i < size; i++)
{
T x;
in >> x;
Add(x);
}
cout << endl;
}
void Output(ostream &out)
{
int frontGet = front;
int x;
while (!IsEmpty())
{
frontGet = (frontGet + 1) % MaxSize;
if (frontGet == rear)
{
cout << queue[frontGet] << " ";
break;
}
else
{
x = queue[frontGet];
out << x << " ";
}
}
cout << endl;
}
private:
int front; //与第一个元素在反时针方向上相差一个位置
int rear; // 指向最后一个元素
int MaxSize; // 队列数组的大小
T *queue; // 数组
};
构造函数:
template<class T>
Queue<T>::Queue(int MaxQueueSize)
{
//创建一个容量为 MaxQueueSize 的空队列
MaxSize = MaxQueueSize + 1;
queue = new T[MaxSize];
front = rear = 0;
}
First函数:
template<class T>
T Queue<T>::First() const
{
if (IsEmpty())
{
throw OutOfBounds();
}
else
{
return queue[(front + 1) % MaxSize];
}
}
Last函数:
template<class T>
T Queue<T>::Last() const
{
if (IsEmpty())
{
throw OutOfBounds();
}
else
{
return queue[rear]; //返回
}
}
Add函数:
template<class T>
Queue<T>& Queue<T>::Add(const T & x)
{
if (IsFull())
{
throw OutOfBounds();
}
else
{
rear = (rear + 1) % MaxSize;
queue[rear] = x;
}
return *this;
}
Delete函数:
template<class T>
Queue<T>& Queue<T>::Delete(T & x)
{
if (IsEmpty())
{
throw OutOfBounds();
}
else
{
front = (front + 1) % MaxSize;
x = queue[front];
}
return *this;
}
获取长度:
template<class T>
int Queue<T>::Length() const
{
if (IsEmpty())
{
return 0;
}
else if (IsFull())
{
return MaxSize - 1;
}
else
{
if (rear>front)
{
return rear - front;
}
else
{
return MaxSize - front + rear; //记录front > rear 的长度
}
}
}
重载函数:
//重载“>>”
template <class T>
istream &operator >> (istream &in, Queue<T> &Q)
{
Q.Input(in);
return in;
}
//重载“<<”
template <class T>
ostream &operator<<(ostream &out, Queue<T> &Q)
{
Q.Output(out);
return out;
}
测试函数:
void testQueue()
{
Queue<int> myQueue(10);
cin >> myQueue;
cout << "myQueue length is " << myQueue.Length() << endl;
int value;
myQueue.Delete(value);
myQueue.Delete(value);
cout << "请输入你要加的数据" << endl;
cin >> value;
myQueue.Add(value);
myQueue.Add(value + 1);
myQueue.Add(value + 2);
cout << myQueue << endl;
cout << "first queue " << myQueue.First() <<
"secend queue is " << myQueue.Last() << endl;
}
输出结果:
队列链表:
图像描述:
链表队列的类定义
/*
数组结构中的 队列 数组与链表描述
对应书中代码:数据结构算法与应用c++描述
程序编写:比卡丘不皮
编写时间:2020年7月16日 2020年7月16日 11:40:55
*/
#pragma once
#include <iostream>
#include "all_error.h"
using namespace std;
template<class T>
class LinkedQueue;
template<class T>
class QueueNode
{
friend LinkedQueue<T>; //声明后会访问私有成员
private:
T data;
QueueNode<T> *link;
};
template<class T>
class LinkedQueue
{
// FIFO对象
public:
LinkedQueue() { front = rear = 0; }
~LinkedQueue();
bool IsEmpty() const //判断是否为空
{
return front == 0;
}
bool IsFull() const; //判断队列是否已满
T Frist() const; //获取队列首元素
T Last() const; //获取队列末尾元素
int Length(); //队列长度
LinkedQueue<T> &Add(const T &x); //添加元素
LinkedQueue<T> &Delete(T &x); //删除元素
void Input(istream &in) //输入链表队列
{
T x;
int size; //队列大小
cout << "请输入队列大小: " << endl;
cin >> size;
cout << "请输入队列元素: " << endl;
while (size && !IsFull())
{
in >> x;
Add(x);
size--;
}
}
void Output(ostream &out) //输出链表队列
{
if (IsEmpty())
throw OutOfBounds();
else
{
QueueNode<T> *next = front;
while (next != 0)
{
out << next->data << " ";
next = next->link;
}
cout << endl;
}
}
private:
QueueNode<T> *front;
QueueNode<T> *rear;
};
其他函数定义:
template<class T>
LinkedQueue<T>::~LinkedQueue()
{
QueueNode<T> * next = new QueueNode<T>;
while (front)
{
next = front->link;
delete front;
front = next;
}
}
template<class T>
bool LinkedQueue<T>::IsFull() const
{
QueueNode<T> *p;
try
{
p = new QueueNode<T>;
delete p;
return false;
}
catch (Noman)
{
return true;
}
}
template<class T>
T LinkedQueue<T>::Frist() const
{
if (IsEmpty())
{
throw OutOfBounds();
}
return front->data;
}
template<class T>
T LinkedQueue<T>::Last() const
{
if (IsEmpty())
{
throw OutOfBounds();
}
return rear->data;
}
template<class T>
int LinkedQueue<T>::Length()
{
if (front == rear)
{
return 0;
}
else
{
QueueNode<T> * next = front;
int len = 0;
while (next)
{
next = next->link;
len++;
}
return len;
}
}
template<class T>
LinkedQueue<T>& LinkedQueue<T>::Add(const T & x)
{
QueueNode<T> * p = new QueueNode<T>;
p->data = x;
p->link = 0;
if (front) //队列不为空,当前末节点指向p
rear->link = p;
else //队列为空
front = p; //p为队列首元素
rear = p; //更新队列末节点
return *this;
}
template<class T>
LinkedQueue<T>& LinkedQueue<T>::Delete(T & x)
{
if (IsEmpty())
throw OutOfBounds();
else
{
x = front->data;
QueueNode<T> *next = front;
front = front->link;
delete next;
}
return *this;
}
//重载“>>”
template <class T>
istream &operator >> (istream &in, LinkedQueue<T> & x)
{
x.Input(in);
return in;
}
//重载“<<”
template <class T>
ostream &operator<<(ostream &out, LinkedQueue<T> &x)
{
x.Output(out);
return out;
}
测试函数:
void testLinkedQueue()
{
LinkedQueue<int> cal;
cin >> cal;
cout << "LinkedQueue length is" << cal.Length() << endl;
cout << cal << endl;
int value;
cal.Delete(value);
cout << "delete a num is " << value << endl;
cout << cal << endl;
}
输出结果: