队列
队列是只能在一端插入,另一端删除元素的线性表。
特性:先进先出
队列术语
队列的基本运算
(1)初始化 :设置队列为空。
(2)判断队列为空:
若为空,则返回TRUE,否则返回FALSE.
(3)判断队列为满:
若为满,则返回TRUE,否则返回FALSE.
(4)取队头元素:取出队头元素。
条件:队列不空。
否则,应能明确给出标识,以便程序的处理。
(5)入队:将元素入队,即放到队列的尾部。
要注意队满的情况
(6)出队:删除当前队头的元素。
要注意队空的情况
队列的实现
存储结构为两种:顺序+链式
1.顺序存储:
在这里若是按照传统的在一个数组之中存储队列的话,在执行入队和出队的操作之后,数组前面的空间会空出,这样即便最终数据存储到了数组的结尾,数组的开端仍然具有空间可以存储数据,这样就不可以判断它为满。
因此,便引出循环队列:
源码:
#include <iostream>
#define maxlen 100 //规定队列之中最多100个数据
using namespace std;
enum error_code{success,underflow,overflow}; //用来记录队列运算的状态
class Queue
{
private:
int count;//用来记录队列中的数据数目
int front,rear; //分别记录队头和队尾
int data[maxlen]; //保存队列中的元素
public:
Queue();
bool empty() const; //判空
bool full() const; //判满
error_code get_front(int &x) const; //取队头元素
error_code append(int x); //入队
error_code serve(); //出队
};
Queue::Queue()
{
count = 0;
front = rear = 0;
}
bool Queue::empty() const
{
return count == 0;
}
bool Queue::full() const
{
return count == maxlen-1;
}
error_code Queue::append(const int x)
{
if(full())
return overflow;
rear = (rear+1) % maxlen; //这样便是构成了循环,当队尾达到了数组的最后,并且队列没有满,则代表数组的前端还有空间,最终rear = maxlen-1时再加元素就会从0开始加
data[rear] = x;
count++;
return success;
}//特别注意,当队列为空时,第一个数据入队时从data[1]开始入队的,此时front为0,rear为1,所以在取队头数据时要取data[front+1]
error_code Queue::get_front(int &x) const
{
if(empty())
return underflow;
x = data[(front+1)%maxlen]; //循环,和append的rear = (rear+1) % maxlen;原理相似
return success;
}
error_code Queue::serve()
{
if(empty())
return underflow;
front = (front+1) % maxlen;
count--;
return success;
}
int main()
{
return 0;
}
2.链式存储
这里要注意选择链首做队首还是链尾做队首
考虑时间复杂度,链首做队首是优选
源码:
#include<iostream>
using namespace std;
enum error_code{success,underflow,overflow};
struct node
{
int data;
node *next;
};
class Queue
{
private:
int count; //元素个数
node *front; //队首
node* rear; //队尾
public:
Queue();
~Queue();
bool empty() const;
bool full() const;
error_code get_front(int &x) const;
error_code append(int x);
error_code serve();
};
Queue::Queue()
{
count = 0;
front = new node;
front->next = NULL;
rear = front;
}
bool Queue::empty() const
{
return count == 0;
}
bool Queue::full() const
{
return false; //链式存储可以任意的添加节点,因此不会出现队满的情况
}
error_code Queue::append(int x)
{
node *s = new node;
s->data = x;
s->next = NULL;
rear->next = s;
rear = s;
count++;
return success;
}//这里要注意添加第一个元素时是在rear(起初front = rear)的next中添加的,也就是说,front的data中没有队中的数据,因此取队首元素时要取front->next中的data
error_code Queue::get_front(int &x) const
{
if(empty())
return underflow;
x = front->next->data;
return success;
}
error_code Queue::serve()
{
if(empty())
return underflow;
node *s = front->next;
front->next = s->next;
delete s;
count--;
if(front->next == NULL) //这里特别注意删除最后一个节点的情况,当删除最后一个节点后,rear不可以丢失,应该让它再回归于front,回到最初的状态
rear = front;
return success;
}
Queue::~Queue()
{
while(!empty())
serve();
delete front;
}
int main()
{
return 0;
}
标准模板库(STL)中的队列
1.头文件:
2.定义方法:
queue<elementyype> + 队列名
如:申请一个int型的队列,名为myqueue
queue<int> myqueue;
3.基本运算:
push(x) 将x压入队列的末端
pop() 弹出队列的第一个元素(队顶元素),注意此函数并不返回任何值
front() 返回第一个元素(队顶元素)
back() 返回最后被压入的元素(队尾元素)
empty() 当队列为空时,返回true
size() 返回队列的长度;
queue<int> myqueue;
myqueue.push(1);
myqueue.empty();
myqueue.size();
myqueue.front();
myqueue.back();
myqueue.pop();
结语
近期要进行数据结构的期末考,因此便总结了一下课堂上所学到的内容。可能会有很多的错误,感谢大家的指正,谢谢。