#Created by: Chen Da
"""
队列类似生活中的排队,为FIFO结构。
两个基本操作:入队push和出队pop。
用单链表可以实现,双链表虽然可以,但是操作比较复杂。
"""
#先实现一个单链表
class Node(object):
def __init__(self,value=None,next=None):
self.value,self.next = value,next
class LinkedList(object):
def __init__(self,max_size=None):
self.max_size = max_size
self.root = Node()
self.length = 0
self.tail_node = None
def __len__(self):
return self.length
def append(self,value):
if self.max_size is not None and self.length > max_size:
raise Exception("The LinkedNode is Full!")
node = Node(value)
tail_node = self.tail_node
if tail_node is None: #只有根节点
self.root.next = node
else:
tail_node.next = node
self.tail_node = node #将尾节点指向添加的节点
self.length += 1
def append_left(self,value):
if self.max_size is not None and self.length > max_size:
raise Exception("The LinkedNode is Full!")
head_node = self.root.next
node = Node(value)
self.root.next = node
node.next = head_node
self.length += 1
def iter_node(self):
cur_node = self.root.next
while cur_node.next is not None:
yield cur_node
cur_node = cur_node.next
yield cur_node
def __iter__(self):
for node in self.iter_node():
yield node.value
def remove(self,value):
pre_node = self.root
cur_node = self.root.next
for cur_node in self.iter_node():
if cur_node.value == value:
pre_node.next = cur_node.next
if cur_node is self.tail_node:
self.tail_node = pre_node
del cur_node
self.length -= 1
return 1
else:
pre_node = cur_node
return -1
def find(self,value):
index = 0
for node in self.iter_node():
if node.value == value:
return index
index += 1
return -1
def pop_left(self):
if self.root.next is None:
raise Exception("单链表已空")
head_node = self.root.next
self.root.next = head_node.next
self.length -= 1
value = head_node.value
del head_node
return value
def clear(self):
for node in self.iter_node():
del node
self.root.next = None
self.length = 0
#################################
#以下是Queue
#################################
class FullError(Exception):
pass
class EmptyError(Exception):
pass
class Queue(object):
def __init__(self,max_size=None):
self.max_size = max_size
self._item_linked_list = LinkedList()
def __len__(self):
return len(self._item_linked_list)
def push(self,value):
if self.max_size is not None and len(self) > max_size:
raise FullError("Queue is Full!")
return self._item_linked_list.append(value)
def pop(self):
if len(self) == 0:
raise EmptyError("Queue is empty!")
return self._item_linked_list.pop_left()
#写一个单测(这里写的不全)
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
if __name__ == "__main__":
test_queue()