05_資料結構_佇列_Python實現
阿新 • • 發佈:2018-12-17
#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()