队列是一种只允许在一端进行插入操作,而在另外一端进行删除操作的线性表,特征是先进先出,包括:顺序存储结 构队列/链式存储结构队列。重点说明:循环队列和链队。(在队列中front为队头指针; rear为队尾指针)
队列:
队列空的条件:rear == front
队列满的条件:(rear + 1) % QueueSize == front
计算队列长度的公式:( rear - front + QueueSize ) % QueueSize
循环队列实现:
#include
#include
using namespace std;
class SqQueue
{
public:
SqQueue() //队列的初始化
{
front = 0;
rear = 0;
}
bool Push(int val); //队尾:入队
bool GetTop(int *rtval); //获取队头元素,但不删除
bool Pop(int *rtval); //获取队头元素,并且删除
bool IsEmpty(); //判断队列是否为空
void Destroy(); //销毁队列
int getLength(); //获取队列的长度
private:
bool IsFull();
static const int a = 10;
int arr[a];
int front; //队头指针
int rear; //队尾指针
};
bool SqQueue::IsFull()
{
return (rear+1)%a == front;
}
bool SqQueue::Push(int val)
{
if (IsFull())
{
return false;
}
arr[rear] = val;
rear = (rear + 1) % a;
return true;
}
bool SqQueue::IsEmpty()
{
return front == rear;
}
bool SqQueue::GetTop(int *rtval)
{
if (IsEmpty())
{
return false;
}
*rtval = arr[front];
return false;
}
bool SqQueue::Pop(int *rtval)
{
if (IsEmpty() || rtval == nullptr)
{
return false;
}
*rtval = arr[front];
front++;
return true;
}
void SqQueue::Destroy()
{
front = 0;
rear = 0;
}
int SqQueue::getLength()
{
return (rear-front+a)%a;
}
int main()
{
SqQueue q1 = SqQueue();
cout<<"1.向队列中插入元素----------------------------------------------------"<
< 6; ++i)
{
q1.Push(i);
}
cout<<"Length = "<
<
链式队列实现:
#include
#include
#include
#include
using namespace std;
class Node //链式存储节点
{
public:
Node(int val):data(val){next = nullptr;}
int data;
Node *next;
};
class HNode
{
public:
HNode(); //构造函数
bool IsEmpty(); //判断队列是否为空
bool Push(int val); //向队列中插入元素
bool GetTop(int *rtval); //获取队头元素,不删除
bool Pop(int *rtval); //获取队尾元素,并删除
void Destroy(); //摧毁队列
private:
Node *front; //队头指针
Node *rear; //队尾指针
};
HNode::HNode()
{
front = nullptr;
rear = nullptr;
}
bool HNode::IsEmpty()
{
return front == nullptr;
}
bool HNode::Push(int val)
{
Node *p = new Node(val);
assert(p != nullptr);
if (IsEmpty())
{
front = p;
rear = p;
}
else
{
rear->next = p;
rear = p;
}
return true;
}
bool HNode::GetTop(int *rtval)
{
if (rtval == nullptr)
{
return false;
}
if (IsEmpty())
{
return false;
}
*rtval = front->data;
return true;
}
bool HNode::Pop(int *rtval)
{
if (rtval == nullptr)
{
return false;
}
if (IsEmpty())
{
return false;
}
GetTop(rtval);
if (front->next == nullptr)//尾节点
{
delete front;
front = nullptr;
rear = nullptr;
}
else //非尾节点
{
Node *p = front;
front = p->next;
delete p;
}
return true;
}
void HNode::Destroy()
{
Node *p;
while (front != nullptr)
{
p = front;
front = p->next;
delete p;
}
rear = nullptr;
}
int main()
{
HNode lq = HNode();
cout<<"1.入队-----------------------------------------------------"<
< 2; ++i) { lq.Push(i); } cout<<"2.获取队首元素,不删除-------------------------------------"<
对于链式队列和循环队列的比较可以从两个方面考虑。时间上:两者基本操作都是常数时间,即O(1),不过循环队列是事先申请好空间,使用期间不再释放,而对于链式队列,每次申请和释放节点也会存在时间开销,若入队出队频繁,则两者还是有一定差异的;空间上:循环队列必须有一个固定长度,故有存储元素个数和空间浪费的问题,而链队则不存在此问题,虽然需要一定空间存储指针域,但是还是可以接受的,故空间上链队更加灵活。