參考博客:https://www.cnblogs.com/stacklike/p/8284550.htmlhtml
# 先進後出 # 以列表實現的簡單棧 class SimpleStack: # 特殊屬性,用以限制class可添加的屬性 __slots__ = ('__items',) def __init__(self): self.__items = [] def is_empty(self): return self.__items == [] def peek(self): return self.__items[len(self.__items)-1] def size(self): return len(self.__items) def push(self, item): self.__items.append(item) def pop(self): self.__items.pop()
class StackFullException(Exception): # 滿棧時要拋出的異常 pass class StackEmptyException(Exception): # 空棧時要拋出的異常 pass class Node: def __init__(self, val=None, nxt=None): self.value = val # 信息域 self.next = nxt # 指針域 def __str__(self): return str(self.value) class Stack: # 初始化一個空棧 def __init__(self, max=0): self._top = None # 棧的頂部元素 self._max = 0 # 棧的最大高度 self.max = max # 用戶將設置的最大棧高度 @property def length(self): if self._top is None: return 0 node = self._top count = 1 # 只要不爲空,就至少有一個節點,所以由1開始 # 藉由節點內的指針來判斷是否有下一個元素,只要就由當前節點跳到下一個節點,並將計數加1 while node.next: node = node.next count += 1 return count @property def is_empty(self): return self._top is None @property def is_full(self): # 滿棧的條件是棧的最大高度不是無限的(設置最大值時會將負數也轉爲0,0就表明了無限大小) # 並且當前棧高等於容許的最大棧高 return bool(self._max and self.length == self._max) @property def max(self): return self._max @max.setter def max(self, m): m = int(m) # 可能傳入值是str或float if m < self.length: # 設置值是否小於當前棧的高度,是則要拋出異常 raise Exception('Stack resize failed, please pop some elements first.') self._max = 0 if m < 0 else m # 輸入值又是不是負數或0,是則都設置爲0,看成無限大小 # 經過逐個壓入傳入的iterable,由空棧構建出一個棧 def init(self, iterable=()): if not iterable: # 傳入一個可迭代對象 return self._top = Node(iterable[0]) # 將其起始元素設置爲棧頂 for item in iterable[1::]: # 將以後的元素也依次壓入棧中,每一次壓入棧定元素都會被替換 node = self._top # 原棧頂元素先儲存起來 self._top = Node(item) # 將當前元素設置爲棧頂 self._top.next = node # 將設置過的棧定的指針指向原來的棧頂 """ | 5 | | 4 | | 3 | | 2 | | 1 | 顯示的樣板 """ def show(self): # 定義的子函數是爲了遍歷棧,這裏用到了生成器 def _traversal(self): node = self._top while node and node.next: yield node node = node.next # 這裏若是不yield,則棧底的元素會沒法被遍歷到,由於最後一個元素並不知足while循環的條件,會停止迭代 yield node # <>^ 左/右/居中對齊 # 生成器也是可迭代的,這裏用高階函數將字符串格式方法映射到每個元素上 print('\n'.join(map(lambda x: '|{:^7}|'.format(str(x)), _traversal(self))) + '\n ' + 7 * '-') def push(self, item): # 若是棧已滿,則拋出異常 if self.is_full: raise StackFullException('Error: trying to push an item into a full stack.') # 若是棧是空的,則直接將item設置爲棧頂,返回便可,由於不須要設置指針 if not self._top: self._top = Node(item) return node = self._top # 先取到原棧頂 self._top = Node(item) # 設置item爲棧頂 self._top.next = node # 將設置過的棧頂的指針指向原棧頂 def pop(self): if self.is_empty: raise StackEmptyException('Error: trying to pop from an empty stack.') node = self._top # 先取到原棧頂 self._top = self._top.next # 將棧頂設置爲原棧頂的下一個元素 return node.value # 返回原棧頂的值 def top(self): return self._top.value if self._top else None def clear(self): # 在已構造的方法上再構造新方法 while self._top: self.pop() s = Stack() s.init([1, 2, 3, 4, 5]) s.show()