栈 / Stack
目录
栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现。
链表栈是以单链表为基础实现的栈数据结构,主要有以下几个关键点:
- 栈顶元素:栈顶元素即为链表的头结点
- 压栈:向链表的头结点插进入栈元素,无表头链表则替换插入元素为头结点
- 弹栈:弹出链表头结点,并将链表头结点替换为下一个元素
Stack based on linked list:
| item3 |
| | |
| V |
| item2 |
| | |
| V |
| item1 |
-------
完整代码
1 class StackEmptyException(Exception): pass 2 3 4 class StackFullException(Exception): pass 5 6 7 class Node: 8 def __init__(self, val=None, nxt=None): 9 self.value = val 10 self.next = nxt 11 12 def __str__(self): 13 return str(self.value) 14 15 16 class Stack: 17 """ 18 Stack based on linked list: 19 | item3 | 20 | | | 21 | V | 22 | item2 | 23 | | | 24 | V | 25 | item1 | 26 ------- 27 """ 28 def __init__(self, max=0): 29 self._top = None 30 self._max = 0 31 self.max = max 32 33 @property 34 def max(self): 35 return self._max 36 37 @max.setter 38 def max(self, m): 39 m = int(m) 40 if m < self.length: 41 raise Exception('Resize stack failed, please pop some elements first.') 42 self._max = m 43 if self._max < 0: 44 self._max = 0 45 46 def init(self, iterable=()): 47 if not iterable: 48 return 49 self._top = Node(iterable[0]) 50 for i in iterable[1:]: 51 node = self._top 52 self._top = Node(i) 53 self._top.next = node 54 55 def show(self): 56 def _traversal(self): 57 node = self._top 58 while node and node.next: 59 yield node 60 node = node.next 61 yield node 62 print('\n'.join(map(lambda x: '|{:^7}|'.format(str(x)), _traversal(self)))+'\n '+7*'-') 63 64 @property 65 def length(self): 66 if self._top is None: 67 return 0 68 node = self._top 69 i = 1 70 while node.next: 71 node = node.next 72 i += 1 73 return i 74 75 @property 76 def is_empty(self): 77 return self._top is None 78 79 @property 80 def is_full(self): 81 return bool(self._max and self.length == self._max) 82 83 def push(self, item): 84 if self.is_full: 85 raise StackFullException('Error: trying to push element into a full stack!') 86 if not self._top: 87 self._top = Node(item) 88 return 89 node = self._top 90 self._top = Node(item) 91 self._top.next = node 92 93 def pop(self): 94 if self.is_empty: 95 raise StackEmptyException('Error: trying to pop element from an empty stack!') 96 node = self._top 97 self._top = self._top.next 98 return node.value 99 100 def top(self): 101 return self._top.value if self._top else self._top 102 103 def clear(self): 104 while self._top: 105 self.pop() 106 107 108 def test(stack): 109 print('\nShow stack:') 110 stack.show() 111 112 print('\nInit linked list:') 113 stack.init([1, 2, 3, 4, 5]) 114 stack.show() 115 116 print('\nPush element to stack:') 117 stack.push(6) 118 stack.push(7) 119 stack.push('like') 120 stack.show() 121 122 print('\nCheck top element:') 123 print(stack.top()) 124 125 print('\nPop element from stack:') 126 e = stack.pop() 127 print('Element %s popped,' % e) 128 stack.show() 129 130 print('\nSet stack max size:') 131 try: 132 stack.max = 1 133 except Exception as e: 134 print(e) 135 136 print('\nSet stack max size:') 137 stack.max = 7 138 print(stack.max) 139 140 print('\nPush full stack:') 141 try: 142 stack.push(7) 143 except StackFullException as e: 144 print(e) 145 146 print('\nClear stack:') 147 stack.clear() 148 stack.show() 149 150 print('\nStack is empty:') 151 print(stack.is_empty) 152 153 print('\nPop empty stack:') 154 try: 155 stack.pop() 156 except StackEmptyException as e: 157 print(e) 158 159 if __name__ == '__main__': 160 test(Stack())