1. 程式人生 > >資料結構入門(一)棧的實現

資料結構入門(一)棧的實現

  從這一篇文章開始,筆者將會正式進入資料結構的領域,後面也將會持續更新。
  本文將會講述一種特殊的線性表結構:棧(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), 歡迎大家關注哦~~