日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python数据结构学习笔记——栈

發(fā)布時間:2024/2/28 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python数据结构学习笔记——栈 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 一、棧的定義和特性
    • (一)棧的定義
    • (二)棧的反轉(zhuǎn)特性
  • 二、實現(xiàn)分析步驟
  • 三、棧的Python實現(xiàn)代碼
  • 四、棧的應(yīng)用
    • (一)匹配圓括號
    • (二)匹配符號
    • (三)模2除法(十進制轉(zhuǎn)二進制)
    • (四)進制轉(zhuǎn)換
  • 結(jié)語

一、棧的定義和特性

(一)棧的定義

棧是一種線性數(shù)據(jù)結(jié)構(gòu),棧是元素的有序集合,其元素的順序取決于添加順序或移除順序,它有兩端,稱作頂端和底端,即對應(yīng)棧的棧頂和棧底,棧中元素的添加稱為入棧,而元素的移除稱為出棧,棧中元素的添加操作和移除操作都發(fā)生在其頂端。

棧中最后添加的元素將最先被移除,棧的排序原則被稱作LIFO,即后進先出,最先添加的元素在棧底,它最后最移出。
簡單來說,可比喻為幾本書或磚頭疊在一起,需要依次從上至下一本一本地拿出書,最下面的那本書最后被拿出。

(二)棧的反轉(zhuǎn)特性

棧的反轉(zhuǎn)特性最明顯的例子體現(xiàn)在瀏覽器的返回鍵中,我們知道在瀏覽網(wǎng)頁時,實際上的網(wǎng)頁是文件,是由 HTML 構(gòu)成的文件,每個網(wǎng)頁文件都有一個唯一的URL(即統(tǒng)一資源定位符)。

當從當前網(wǎng)頁跳轉(zhuǎn)到另一個網(wǎng)頁頁面時,當前瀏覽的網(wǎng)頁處于棧頂,而之前的網(wǎng)頁相對當前網(wǎng)頁位于棧底,也就是這些網(wǎng)頁的URL都被存放在一個棧中。

二、實現(xiàn)分析步驟

通過Python中的類與對象,在類中定義幾個方法,且使用列表來實現(xiàn)棧的相關(guān)操作,棧的操作有:
1、創(chuàng)建一個空棧,通過構(gòu)造方法創(chuàng)建一個空列表;

class Stack:def __init__(self):self.items = [] # 創(chuàng)建一個空棧,它不需要參數(shù),且會返回一個空棧

2、向棧(棧頂)中添加元素,通過列表的append()或insert()實現(xiàn)添加新的元素至棧中。(若將列表的尾部作為棧的頂端,則通過append()實現(xiàn);而若將列表的頭部作為棧的頂端,則通過insert()實現(xiàn),insert()第一個參數(shù)表示索引位置,第二個參數(shù)即要添加的元素,由于是向棧頂添加元素,則第一個參數(shù)為0(列表的下標從0開始));

def push(self, item):self.items.append(item) # 將一個元素添加到棧的頂端,它需要一個參數(shù)item,且無返回值【self.items.insert(0,item)】

3、刪除棧頂元素,通過列表的pop()實現(xiàn)刪除棧頂?shù)脑亍?#xff08;若將列表的尾部作為棧的頂端,pop()內(nèi)無參數(shù),即此時刪除列表的末尾元素,也就是棧的頂端元素;而若將列表的頭部作為棧的頂端,則pop(0)表示移除列表中下標為0的元素);

def pop(self):return self.items.pop() # 將棧頂?shù)脑匾瞥?#xff0c;它不需要參數(shù),但會返回頂端的元素,且修改棧的內(nèi)容【return self.items.pop(0)】

4、返回棧頂元素,若將列表的尾部作為棧的頂端,則通過len()先取得列表的長度,由于下標是從0開始,所以要減1;而若將列表的頭部作為棧的頂端,則直接通過索引列表下標為0的元素);

def peek(self):return self.items[len(self.items) - 1] # 返回棧頂端的元素,它不需要參數(shù),不會修改棧的內(nèi)容【return self.items[0]】

5、檢查棧是否為空,通過比較運算符“==”比較棧是否為空,若為空,則返回布爾值False,若不為空,則返回True;

def isEmpty(self):return self.items == [] # 檢查棧是否為空,它不需要參數(shù),且會返回一個布爾值

6、返回棧中元素數(shù)目,通過len()取列表的長度,即返回棧中元素的數(shù)目。

def size(self):return len(self.items) # 返回棧中元素的數(shù)目,它不需要參數(shù),且會返回一個整數(shù)

三、棧的Python實現(xiàn)代碼

將列表的尾部作為棧的頂端:

# 通過列表實現(xiàn)棧的操作(以列表尾部作為棧的頂端) class Stack:def __init__(self):self.items = [] # 創(chuàng)建一個空棧,它不需要參數(shù),且會返回一個空棧def isEmpty(self):return self.items == [] # 檢查棧是否為空,它不需要參數(shù),且會返回一個布爾值def push(self, item):self.items.append(item) # 將一個元素添加到棧的頂端,它需要一個參數(shù)item,且無返回值def pop(self):return self.items.pop() # 將棧頂?shù)脑匾瞥?#xff0c;它不需要參數(shù),但會返回頂端的元素,且修改棧的內(nèi)容def peek(self):return self.items[len(self.items) - 1] # 返回棧頂端的元素,它不需要參數(shù),不會修改棧的內(nèi)容def size(self):return len(self.items) # 返回棧中元素的數(shù)目,它不需要參數(shù),且會返回一個整數(shù)s = Stack() # s是一個新創(chuàng)建的空棧,創(chuàng)建一個對象,即對象名稱=類名稱() print(s.isEmpty()) # 檢查棧是否為空 s.push("wddd") s.push("w") s.push(123) print(s.peek()) # 返回棧最頂端的元素 print(s.size()) # 返回當前棧中的元素數(shù)目 s.push(False) print(s.size()) print(s.isEmpty()) s.push(0.2) print(s.pop()) # 刪除棧頂元素 print(s.peek()) print(s.size())

運行結(jié)果如下:

四、棧的應(yīng)用

(一)匹配圓括號

我們知道圓括號由左括號“(”和右括號“)”進行匹配的,通過創(chuàng)建一個空棧來保存括號,從左至右依次處理括號,若匹配到左括號則通過push()方法將其添加至棧中,而若匹配到右括號則通過pop()方法刪除棧頂元素,最后若所有括號都匹配則棧為空,程序會返回一個布爾值來表示括號是否匹配。
程序完整代碼及解析如下:

# 通過列表實現(xiàn)棧的操作(以列表尾部作為棧的頂端) class Stack:def __init__(self):self.items = [] # 創(chuàng)建一個空棧,它不需要參數(shù),且會返回一個空棧def isEmpty(self):return self.items == [] # 檢查棧是否為空,它不需要參數(shù),且會返回一個布爾值def push(self, item):self.items.append(item) # 將一個元素添加到棧的頂端,它需要一個參數(shù)item,且無返回值def pop(self):return self.items.pop() # 將棧頂?shù)脑匾瞥?#xff0c;它不需要參數(shù),但會返回頂端的元素,且修改棧的內(nèi)容def peek(self):return self.items[len(self.items) - 1] # 返回棧頂端的元素,它不需要參數(shù),不會修改棧的內(nèi)容def size(self):return len(self.items) # 返回棧中元素的數(shù)目,它不需要參數(shù),且會返回一個整數(shù)# 定義一個有參函數(shù)Par_Checker(),其參數(shù)parenthesis是輸入的括號 def Par_Checker(parenthesis):s = Stack() # s是一個新創(chuàng)建的空棧,創(chuàng)建一個對象balanced = Trueindex = 0while index < len(parenthesis) and balanced: # 若當前索引值小于輸入的括號的總長度且變量balanced的值為正確時,一直執(zhí)行while循環(huán)下去symbol = parenthesis[index]# 取輸入的括號賦給變量symbol,變量index的初值為0if symbol == "(": # 若匹配到左括號則通過push()方法將其添加至棧中s.push(symbol)else:if s.isEmpty(): # 檢查棧是否為空,它不需要參數(shù),會返回一個布爾值balanced = False # 棧為空,變量balanced的值變?yōu)镕alseelse:s.pop() # 若匹配到右括號則通過pop()方法刪除棧頂元素index = index + 1 # 索引加一,對下一個括號進行檢查if balanced and s.isEmpty(): # 如果棧為空,則代表所有括號都匹配成功return Trueelse:return False#測試 print(Par_Checker("(()((")) print(Par_Checker(")((")) print(Par_Checker("(()(()))"))

運行結(jié)果如下:

(二)匹配符號

通過改進匹配圓括號的程序從而實現(xiàn)對符號“()”、“[]”和“{}”的匹配,在原有的基礎(chǔ)上加了一個函數(shù)matches(),該函數(shù)檢查每一個從棧頂移除的符合是否與當前的右符合相匹配,匹配符號的程序完整代碼及解析如下:

# 通過列表實現(xiàn)棧的操作(以列表尾部作為棧的頂端) class Stack:def __init__(self):self.items = [] # 創(chuàng)建一個空棧,它不需要參數(shù),且會返回一個空棧def isEmpty(self):return self.items == [] # 檢查棧是否為空,它不需要參數(shù),且會返回一個布爾值def push(self, item):self.items.append(item) # 將一個元素添加到棧的頂端,它需要一個參數(shù)item,且無返回值def pop(self):return self.items.pop() # 將棧頂?shù)脑匾瞥?#xff0c;它不需要參數(shù),但會返回頂端的元素,且修改棧的內(nèi)容def peek(self):return self.items[len(self.items) - 1] # 返回棧頂端的元素,它不需要參數(shù),不會修改棧的內(nèi)容def size(self):return len(self.items) # 返回棧中元素的數(shù)目,它不需要參數(shù),且會返回一個整數(shù)# 定義一個有參函數(shù)matches(),該函數(shù)檢查每一個從棧頂移除的符合是否與當前的右符合相匹配 def matches(left, right):left = "([{"right = ")]}"return left.index(left) == right.index(right) # index()用于檢查子字符串是否在字符串中# 定義一個有參函數(shù)Par_Checker(),其參數(shù)parenthesis是輸入的括號 def Par_Checker(parenthesis):s = Stack() # s是一個新創(chuàng)建的空棧,創(chuàng)建一個對象balanced = Trueindex = 0while index < len(parenthesis) and balanced: # 若當前索引值小于輸入的符號的總長度且變量balanced的值為正確時,一直執(zhí)行while循環(huán)下去symbol = parenthesis[index] # 取輸入的符號賦給變量symbol,變量index的初值為0if symbol in "([{": # 若匹配到左符號則通過push()方法將其添加至棧中s.push(symbol)else:if s.isEmpty(): # 檢查棧是否為空,它不需要參數(shù),會返回一個布爾值balanced = False # 棧為空,變量balanced的值變?yōu)镕alseelse:top = s.pop() # 若匹配到右符號則通過pop()方法刪除棧頂元素if not matches(top, symbol): # 調(diào)用matches()函數(shù)檢查每一個從棧頂移除的符合是否與當前的右符合相匹配,即若未匹配執(zhí)行以下語句balanced = Falseindex = index + 1 # 索引加一,對下一個符號進行檢查if balanced and s.isEmpty(): # 如果棧為空,則代表所有符號都匹配成功return Trueelse:return False#測試 print(Par_Checker("(({)(")) print(Par_Checker("](")) print(Par_Checker("{([]})"))

運行結(jié)果如下:

(三)模2除法(十進制轉(zhuǎn)二進制)

我們知道將十進制轉(zhuǎn)二進制可以通過模2除法的方法實現(xiàn),也就是除2取余,逆序排列,如下十進制25轉(zhuǎn)換為二進制:

最后可得25=0001 1001=11001:

我們從步驟上可以看出,計算出的第一個余數(shù)是得到結(jié)果的最后一位,而最后計算出的余數(shù)是結(jié)果的第一位,所以可以將得到的二進制數(shù)看成一系列數(shù)字,創(chuàng)建一個空棧,通過一系列方法得到二進制數(shù)字。
模2除法的程序完整代碼及解析如下:

# 通過列表實現(xiàn)棧的操作(以列表尾部作為棧的頂端) class Stack:def __init__(self):self.items = [] # 創(chuàng)建一個空棧,它不需要參數(shù),且會返回一個空棧def isEmpty(self):return self.items == [] # 檢查棧是否為空,它不需要參數(shù),且會返回一個布爾值def push(self, item):self.items.append(item) # 將一個元素添加到棧的頂端,它需要一個參數(shù)item,且無返回值def pop(self):return self.items.pop() # 將棧頂?shù)脑匾瞥?#xff0c;它不需要參數(shù),但會返回頂端的元素,且修改棧的內(nèi)容def peek(self):return self.items[len(self.items) - 1] # 返回棧頂端的元素,它不需要參數(shù),不會修改棧的內(nèi)容def size(self):return len(self.items) # 返回棧中元素的數(shù)目,它不需要參數(shù),且會返回一個整數(shù)# 創(chuàng)建一個有參函數(shù)DivideBy2(),參數(shù)為一個十進制數(shù) def DivideBy2(decNumber):s = Stack() # s是一個新創(chuàng)建的空棧,創(chuàng)建一個對象while decNumber > 0: # 若輸入的十進制大于0,則執(zhí)行while循環(huán)一直下去rem = decNumber % 2 # 參數(shù)rem為余數(shù),即十進制數(shù)每次除2得到的余數(shù)s.push(rem) # 通過push()方法將得到的余數(shù)添加到棧的頂端decNumber = decNumber // 2 # 輸入的十進制整數(shù)除2,即十進制與2的整數(shù)商binString = "" # 定義一個空字符串binString用于存放二進制數(shù)字while not s.isEmpty(): # 若棧不為空,則執(zhí)行while循環(huán)一直下去binString = binString + str(s.pop()) # 通過pop()方法將棧頂?shù)脑匾瞥?#xff0c;通過str()轉(zhuǎn)換為字符串類型并通過"+"拼接賦值給字符串binStringreturn binString # 得到的二進制值print(DivideBy2(17)) print(DivideBy2(255)) print(DivideBy2(1024)) print(DivideBy2(2022))

運行結(jié)果如下:

(四)進制轉(zhuǎn)換

根據(jù)十進制轉(zhuǎn)二進制的程序代碼可以進一步改進,首先該函數(shù)可以另外定義一個參數(shù)base,它表示相應(yīng)的進制數(shù)(二進制、八進制、十六進制),另外創(chuàng)建一個字符串digits,由于有十進制轉(zhuǎn)十六進制,所以該字符串的內(nèi)容應(yīng)該有ABCDEF,再加上數(shù)字0-9,即該字符串的內(nèi)容為“0123456789ABCDEF”,它用于存儲對應(yīng)位置上的數(shù)字,當從棧中移除一個十進制余相應(yīng)的進制數(shù)得到的余數(shù)時,就可以作為訪問數(shù)字的下標,即對應(yīng)的數(shù)字會被添加到結(jié)果中,最后再通過pop()方法將棧頂?shù)脑匾瞥?#xff0c;通過對字符串索引的方式依次索引移除的元素,并通過"+"拼接賦值給字符串newString。
十進制轉(zhuǎn)其他進制(二進制、八進制、十六進制)的程序完整代碼及解析如下:

# 通過列表實現(xiàn)棧的操作(以列表尾部作為棧的頂端) class Stack:def __init__(self):self.items = [] # 創(chuàng)建一個空棧,它不需要參數(shù),且會返回一個空棧def isEmpty(self):return self.items == [] # 檢查棧是否為空,它不需要參數(shù),且會返回一個布爾值def push(self, item):self.items.append(item) # 將一個元素添加到棧的頂端,它需要一個參數(shù)item,且無返回值def pop(self):return self.items.pop() # 將棧頂?shù)脑匾瞥?#xff0c;它不需要參數(shù),但會返回頂端的元素,且修改棧的內(nèi)容def peek(self):return self.items[len(self.items) - 1] # 返回棧頂端的元素,它不需要參數(shù),不會修改棧的內(nèi)容def size(self):return len(self.items) # 返回棧中元素的數(shù)目,它不需要參數(shù),且會返回一個整數(shù)# 創(chuàng)建一個有參函數(shù)BaseConverter(),參數(shù)為進制數(shù)和進制 def BaseConverter(decNumber, base):digits = "0123456789ABCDEF" # 創(chuàng)建一個字符串digits,存儲對應(yīng)位置上的數(shù)字,當從棧中移除一個余數(shù)時,它可以被用作訪問數(shù)字的下標,對應(yīng)的數(shù)字會被添加到結(jié)果中s = Stack()while decNumber > 0: # 若輸入的進制數(shù)大于0,則執(zhí)行while循環(huán)一直下去rem = decNumber % base # 參數(shù)rem為余數(shù),即進制數(shù)每次除相應(yīng)的進制得到的余數(shù)s.push(rem) # 通過push()方法將得到的余數(shù)添加到棧的頂端decNumber = decNumber // base # 輸入的進制數(shù)整數(shù)除相應(yīng)的進制newString = "" # 定義一個空字符串newString用于存放二進制數(shù)字while not s.isEmpty(): # 若棧不為空,則執(zhí)行while循環(huán)一直下去newString = newString + digits[s.pop()] # 通過pop()方法將棧頂?shù)脑匾瞥?#xff0c;通過對字符串索引的方式依次索引移除的元素,并通過"+"拼接賦值給字符串newStringreturn newString # 得到的相應(yīng)進制值#測試 print(BaseConverter(17, 2)) print(BaseConverter(255, 8)) print(BaseConverter(1024, 16)) print(BaseConverter(2022, 16))

運行結(jié)果如下:

結(jié)語

參考書籍:《Python數(shù)據(jù)結(jié)構(gòu)與算法分析 第2版》
[美] 布拉德利·米勒(Bradley N. Miller) 戴維·拉努姆(DavidL. Ranum)|譯者:呂能 刁壽鈞

以上就是本次Python數(shù)據(jù)結(jié)構(gòu)學習筆記棧的全部內(nèi)容,篇幅較長,感謝您的閱讀和支持,若有表述或代碼中有不當之處,望指出!您的指出和建議能給博主帶來很大的動力!!!

總結(jié)

以上是生活随笔為你收集整理的Python数据结构学习笔记——栈的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。