您的位置:首页 > 理论基础 > 数据结构算法

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

2016-11-05 10:47 1026 查看
       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)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息