队列:先进先出。 FIFO结构。5,4,3,2,1
如何FIFO呢?
已经学了array(数组) ,list(列表), linkedlist(单链表), DLL(双链表)
队列实现需要push(入队)和从队首pop(出队)
list 插入时间复杂度较高,
单链表:popleft和append都是O(1)。可以使用。
双链表:也可以用,但是实现相对复杂。
这里使用单链表实现队列:
方便查看直接把04章的单链表代码拷贝过来。
class Node(object):
def __init__(self, value=None, next=None):
self.value, self.next = value, next
class LinkedList(object):
def __init__(self, maxsize=None):
self.maxsize = maxsize
self.root = Node()
self.length = 0
self.tailnode = None
def __len__(self):
return self.length
def append(self, value):
if self.maxsize is not None and len(self) > self.maxsize:
return Exception("Full")
node = Node(value)
tailnode = self.tailnode
if tailnode is None: # 第一个插入的值作为root入口的下一个节点。
self.root.next = node
else:
tailnode.next = node # 后面每加一个值就作为尾节点。
self.tailnode = node
self.length += 1
def appendLeft(self, value):
headnode = self.root.next
node = Node(value)
self.root.next = node
node.next = headnode
self.length += 1
def iter_node(self):
# 遍历节点,每次返回当前节点的下一个节点
currnode = self.root.next
while currnode is not self.tailnode:
yield currnode
currnode = currnode.next
yield currnode # 返回最后的尾节点
def __iter__(self): # 需要和上面函数配合完成遍历节点
for node in self.iter_node():
yield node.value
def remove(self, value): # O(n)
prenode = self.root
currnode = self.root.next
while currnode.next is not None:
if currnode.value == value:
prenode.next = currnode.next
del currnode
self.length -= 1
return
def find(self, value): # O(n)
index = 0
for node in self.iter_node():
if node.value == value:
return index
index += 1
return -1
def popleft(self): # O(1)
if self.root.next is None:
raise Exception("pop from empty.")
headnode = self.root.next
self.root.next = headnode.next
self.length -= 1
value = headnode.value
del headnode
return value
def clear(self):
for node in self.iter_node():
del node
self.root.next = None
self.length = 0
def test_linked_list():
ll = LinkedList()
ll.append(0)
ll.append(1)
ll.append(2)
assert len(ll) == 3
assert ll.find(2) == 2
assert ll.find(3) == -1
ll.remove(0)
assert len(ll) == 2
assert ll.find(0) == -1
assert list(ll) == [1, 2]
ll.appendLeft(0)
assert list(ll) == [0, 1, 2]
assert len(ll) == 3
headvalue = ll.popleft()
assert headvalue == 0
assert len(ll) == 2
assert list(ll) == [1, 2]
ll.clear()
assert len(ll) == 0
"""下面实现队列"""
class FullError(Exception):
pass
class EmptyError(Exception):
pass
class Queue(object):
def __init__(self, maxsize=None):
self.maxsize = maxsize
self._item_linked_list = LinkedList()
def __len__(self):
return len(self._item_linked_list)
def push(self, value):
if self.maxsize is not None and len(self) >= self.maxsize:
raise FullError("queue full")
return self._item_linked_list.append(value)
def pop(self):
if len(self) <= 0:
raise EmptyError("queue empty")
return self._item_linked_list.popleft()
def test_queue():
q = Queue()
q.push(0)
q.push(1)
q.push(2)
assert len(q) == 3
assert q.pop() == 0
assert q.pop() == 1
assert q.pop() == 2