python数据结构学习笔记-2016-11-05-01-队列ADT及其实现

       8.1 队列ADT

       队列(queue):只能在一端插入元素,在另一端删除元素的容器。其特点是先进先出(first-in first-out, FIFO)。

       插入元素的一端称为后端(back),也称为队尾,删除元素德一端称为前端(front),也称为队头。

       其具有如下属性:

  • Queue():创建空队列;
  • isEmpty():判断当前队列是否为空;
  • length():返回队列长度;
  • enqueue():添加元素到队尾;
  • dequeue():从队头删除元素。
       8.2 队列的实现

       有三种方式可以实现队列,分别是python列表、数组以及链表。

       基于python列表的实现

       这种方式最简单。

#-*-coding: utf-8-*-

# 使用python列表实现队列

class Queue(object):
    def __init__(self):
        self._qList = list()

    def isEmpty(self):
        return len(self) == 0

    def __len__(self):
        return len(self._qList)

    def enqueue(self, item):
        self._qList.append(item)

    def dequeue(self):
        assert not self.isEmpty(), "Cannot dequeue from an empty queue."
        return self._qList.pop(0)

       从以上操作可以看出,length()和isEmpty()的时间复杂度是O(1)。enqueue()和dequeue()的时间复杂度是O(n)。


       基于数组的实现

       这里的数组可以看成一个环形数组(circular array),另外还需要两个指针,一个指向队头,另一个指向队尾。如下图:


       其特点是在插入和删除元素时,其他元素不需要进行移位,只需要移动两个指针便可。

       在进行插入元素时,如果数组还有足够的容量,添加新元素,back指针向后移动一位。删除元素时,只需把要删除元素所在位置设置为None,再将front指针后移一位即可。但也有可能碰到以下特殊情况:


       在这种情况下,由于我们使用的是环形数组,新元素会被添加到数组索引0的位置,而back指针也会移动至该位置。

       数组实现方式的缺陷显然是容量有限。

#-*-coding: utf-8-*-

# 使用数组来实现队列

from myarray import Array

class Queue(object):
    def __init__(self, maxSize):
        self._count = 0
        self._front = 0 # 初始化front指针指向索引0的位置
        self._back = maxSize - 1 # 初始化back指针指向索引maxSize - 1的位置
        self._qArray = Array(maxSize)

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

    def isFull(self):
        return self._count == len(self._qArray)

    def __len__(self):
        return self._count

    def enqueue(self, item):
        assert not self.isFull(), "Cannot enqueue to a full queue."
        maxSize = len(self._qArray)
        self._back = (self._back + 1) % maxSize # 注意此处
        self._qArray[self._back] = item
        self._count += 1

    def dequeue(self):
        assert not self.isEmpty(), "Cannot dequeue from an empty queue."
        item = self._qArray[self._front]
        maxSize = len(self._qArray)
        self._front = (self._front + 1) % maxSize
        self._count -= 1
        return item
       基于数组的实现方式,所有方法的时间复杂度都是O(1),因为没有元素移位出现。


       基于链表的实现

       基于链表的实现方式,是在一个链表上使用头指针和尾指针,头指针指向队头,尾指针指向队尾。

#-*-coding: utf-8-*-

# 使用链表实现队列

class Queue(object):
    def __init__(self):
        self._qhead = None
        self._qtail = None
        self._count = 0

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

    def __len__(self):
        return self._count

    def enqueue(self, item):
        node = _QueueNode(item)
        if self.isEmpty():
            self._qhead = node
        else:
            self._qtail.next = node
        self._qtail = node
        self._count += 1

    def dequeue(self):
        assert not self.isEmpty(), "Cannot dequeue from an empty queue."
        node = self._qhead
        if self._qhead is self._qtail:
            self._qtail = None
        self._qhead = self._qhead.next
        self._count -= 1
        return node.item

class _QueueNode(object):
    def __init__(self, item):
        self.item = item
        self.next = None
        在链表实现方式中,所有方法的时间复杂度都是O(1)。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值