队列

队列

栈是一种基于先进先出(FIFO)策略的集合类型,队列是日常现象的排队模型,进入队列的元素维持它们的原有顺序,并按照此顺序移出队列。

队列

队列的基本操作

由此可以定义队列的基本操作:

  1. void enqueue(Item item)
  2. Item dequeue()
  3. boolean isEmpty()
  4. int size()

以上就是队列支持的所有操作,这是一个严格的接口说明书,没有额外的多余操作,这是一个良好的习惯,仅提供必需的接口,简洁而清晰(有些语言的库函数提供了Queue功能,但是却提供了额外的操作,比如可以在顶和底添加和删除元素)。

队列的实现

依照上述的接口说明书,我们可以通过各种结构来实现队列,最容易想到的就是上篇文章提到的线性存储结构,数组和链表。

数组实现

构造固定容量的一个数组, 记录队列的最大容量,并且维护两个指针first和last,用于记录队列头和队列尾,同时记录一个计数器n,记录当前队列中的元素个数。每次在数组的尾部进行添加元素则移动last指针,增加计数器;从队列头部取出元素则移动first指针,减少计数器。当last或者first移动到数组尾部则回绕到数组头部。当该队列固定容量数组达到上限,即数组已满,需要扩展数组容量(比如容量翻倍),把原来数据全部搬家到新数组,后续使用新数组继续操作。 随着数据的dequeue出队列,数据越来越少,数组空闲了很多空间,因此需要处理此种情况,当数据占用比例小于一定的数值,则需要重新申请一个小空间的数组,把数据搬家到此数组,把原来的大数组空间释放。

链表实现

使用前面文章描述的双循环链表,可以方便的实现队列所支持的操作。

初始状态,构造一个双循环链表,仅包含头节点。

  1. void enqueue(Item item)
    从双循环链表的尾部添加节点。

  2. Item dequeue()
    从双循环链表的头部删除节点。

  3. boolean isEmpty()
    判断头结点是否指向头结点。

  4. int size()
    内部维护一个计数器,当enqueue时增加1,当dequeue时,减小1。

依靠双循环链表的通用结构,方便的实现队列,时间和空间复杂度为O(1),简洁而高效。

队列的应用

队列是一种常用的结构,如计算机科学中的生产者消费者问题,生产者生产数据放入队列尾部,消费者从队列头部取出数据处理。

源码参考

class LinkQueue(object):
    '''使用双循环链表实现队列'''
    def __init__(self):
        self.__N = 0
        self.__dlink = DoubleCircleList()

    def enqueue(self, v):
        self.__dlink.add_tail(v)
        self.__N += 1

    def dequeue(self):
        if self.isEmpty():
            raise Exception, "queue is empty when dequeue"
        node = self.__dlink.del_head()
        self.__N -= 1
        return node.v

    def peek(self):
        if self.isEmpty() == 0:
            raise Exception, "queue is empty when peek"
        return self.__dlink.get_head().v

    def isEmpty(self):
        return self.__N == 0

    def size(self):
        return self.__N

    def iterator(self):
        return self.__dlink.iterator()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值