資料結構入門(一)棧的實現
從這一篇文章開始,筆者將會正式進入資料結構的領域,後面也將會持續更新。
本文將會講述一種特殊的線性表結構:棧(stack)。
棧,是限定僅在表尾進行插入或刪除操作的線性表。因此,對棧來說,表尾端有其特殊含義,稱為棧頂(top),相應地,表頭端稱為棧底(bottom)。不含任何元素的空表稱為空棧。
假設棧\(S=(a_{1},a_{2},...,a_{n}),\)則稱\(a_{1}\)為棧底元素,\(a_{n}\)為棧頂元素。棧中元素按\(a_{1},a_{2},...,a_{n}\)的次序進棧,退棧的第一個元素應為棧頂元素。換句話說,棧的修改是按後進先出的原則進行的,如下圖所示:
因此,棧又被稱為後進先出(last in first out)的線性表(簡稱LIFO結構)。
棧的基本操作有:棧的初始化,判斷是否為空,取棧頂元素,在棧頂進行插入和刪除等。我們將藉助Python中的列表來實現棧這個結構,完整的Python程式碼(Stack.py)如下:
# -*- coding: utf-8 -*- class Empty(Exception): # Error attempting to access an element from an empty container pass class Stack: # initialize def __init__(self): self.__data = [] # length of Stack def __len__(self): return len(self.__data) # whether the Stack is empty def is_empty(self): return len(self.__data) == 0 # push an element is Stack def push(self, e): self.__data.append(e) # top element of Stack def top(self): if self.is_empty(): raise Empty('Stack is empty') return self.__data[-1] # remove the top element of Stack def pop(self): if self.is_empty(): raise Empty('Stack is empty') return self.__data.pop()
在上述程式碼中,我們先定義了一個錯誤型別Empty,當你試圖從一個空的容器中獲取元素時,則會提示這個錯誤。接下來,定義了類Stack來實現棧,實現的方法分別為:棧的初始化,棧的長度,判斷棧是否為空,元素入棧,棧頂元素,元素退棧。
我們先來測試下棧的使用情況,程式碼如下:
from Stack import Stack s = Stack() s.push(5) s.push(3) print(len(s)) print(s.pop()) print(s.is_empty()) print(s.pop()) print(s.is_empty()) s.push(7) s.push(9) print(s.top()) s.push(4) print(len(s)) print(s.pop())
輸出結果如下:
2
3
False
5
True
9
3
4
OK,我們已經實現了棧這個結構。接下來,我們將使用棧結構去解決一個實際問題:數的進位制轉換,作為棧的第一個應用例項,後續筆者會有專門的文章講述棧的應用。
十進位制數N和其他d進位制數的轉換是計算機實現計算得基本問題,其解決方法如下:
N = (N div d) * d + N mod d(其中,div為整除運算,mod為求餘運算)。
例如,\((2018)_{10}=(3742)_{8}\),其運算結果如下:
N | N div 8 | N mod 8 |
---|---|---|
2018 | 252 | 2 |
252 | 31 | 4 |
31 | 3 | 7 |
3 | 0 | 3 |
因此,如果我們需要將十進位制數N轉化為其他d進位制數,比如8,我們只需要將第三列的N mod 8逆序輸出即可,這可以藉助棧很好地實現,實現的Python程式碼如下:
from Stack import Stack
# 十進位制數
N = 2018
s = Stack()
while N:
s.push(N % 8)
N //= 8
# 八進位制數
while not s.is_empty():
print(s.pop(), end='')
輸出結果如下:
3742
搞定,程式碼非常之簡潔!如果我們用普通方法去實現這個程式,可能會稍顯麻煩,而使用棧,就會簡單很多。
本次分享到此結束,歡迎大家交流~~
注意:本人現已開通微信公眾號: Python爬蟲與演算法(微訊號為:easy_web_scrape), 歡迎大家關注哦~~