3.2 队列

基本概念

队列定义及特点

  • 队列(queue)是一种只能在某一段进行插入,在另一端进行删除的线性表。
  • 将进行插入和删除的两端分别称为队首(front)和队尾(rear)。
  • 将元素进入队列成为入队(enqueue),将元素从队列中删除成为出队(dequeue)。
  • 队列具有FIFO(First In, First Out)的特性。

队列的基本操作

名称作用
create()创建一个空的队列
destroy(q)销毁一个队列q
empty(q)判断队列q是否为空
enqueue(q, v)将元素v进入队列q
dequeue(q)将队列q的首元素出列
front(q)返回队列q的首元素

队列的实现

同栈一样,队列也是一种特殊的线性表。因此利用线性表的基本操作也能够实现一个队列。
利用顺序存储结构实现队列,直接使用数组较为便利,因此这里没有像栈的实现那样利用之前实现的线性表了。
利用顺序存储结构存储队列的问题在于如何在 O(1) 的时间内实现入队和出队。因为队列的容量 c 是固定的,因此我们可以维护两个指针,分别表示队首和队尾。只要入队,则将队首指针front向后移动一位,出队,则需要将队尾指针rear向后移动一位。为了实现空间的有效利用,必须实现环形队列,也就是指针可以从结尾跳到开头(circular queue)。所幸的是,可以使用求余操作实现这个目的,即p=(p+1)modc(设指针为 p )。

/**
* 顺序队列类
*/
template<typename _Ty, int capacity = 64>
class SeqQueue{
private:
    _Ty _data[capacity];
    int _front;
    int _rear;
    int _length;
public:
    /**
    * 构造函数,创建一个空队列
    */
    SeqQueue():_front(0), _rear(0), _length(0){}
    /**
    * 析构函数
    */
    ~SeqQueue(){}
    /**
    * 判断队列是否为空
    * @return bool 空栈返回true,否则false
    */
    bool empty(){
        return _length == 0;
    }
    /**
    * 返回栈顶元素
    * @return _Ty & 栈顶元素
    */
    _Ty & front(){
        assert(!this->empty());
        return _data[_rear];
    }
    /**
    * 将元素入列
    * @param _Ty & value 需要入列的元素
    */
    void enqueue(_Ty value){
        assert(_length < capacity);
        _data[_front++ % capacity] = value; //注意后++不是前++
        _length++;
    }
    /**
    * 将队首元素出列
    */
    void dequeue(){
        assert(!this->empty());
        _rear = (_rear++) % capacity;
        _length--;
    }
    /**
    * 返回队列的实际长度
    * @return int 队列的实际长度
    */
    int length(){
        return _length;
    }
};

利用链式存储结构实现队列,除了需要维护头指针外,还需要维护尾指针。这样在入队时,可以将其插入尾部,而出队,则将head->next(第一个结点)删除即可。
至于STL的queuestack一样,也是用deque这种容器实现的一种配接器。STL的deque的存储结构比较复杂,它保证了插入和删除的摊还时间都是O(1),同时能够实现随机迭代器。其实现可以参考STL源码剖析。

队列的应用

队列在数据结构和算法中的应用也很多,比较经典的就是图的广度优先搜索(Broaden First Search)。
对于广搜的简要描述如下:

取一个顶点v_0进入队列q
while q不空
    f = q.front
    检查f的下一个可达且未走过的顶点集合V
    foreach v in V
        q.enqueue(v)
    标记f已经走过
    q.dequeue

队列还有很多在其他方面的应用,比如操作系统、网络、分布式等,其核心在于资源分配和任务调度。
除此之外,队列也能够模拟一些实际中的类似于队列的问题。

Summary

  • 队列的基本特性

    队列是一种特殊的,操作受限的线性表。只能在一端进行插入,在另一端进行删除。这种FIFO的特性保证了队列只能够按照原序输出。

  • 队列的实现

    队列作为线性表,同样有顺序存储和链式存储两种存储结构。使用链式存储结构时,需要保留尾指针,以便在 O(1) 时间内进行操作;使用顺序存储结构时,为了提高空间利用率,通常使用求余法构造环形队列。

  • 队列的应用

    队列的一个重要应用就是实现BFS。除此之外,队列在操作系统等方面,涉及到任务调度和资源分配时,也有着非常多的应用。普通队列严格执行FIFO特性,而后面的优先队列(利用binary heap实现)则按照优先级出队。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值