網(wǎng)站首頁 編程語言 正文
什么是棧
棧有時也被稱作“下推棧”。它是有序集合,添加操作和移除操作總發(fā)生在同一端,即棧的?“頂端”,棧的另一端則被稱為?“底端”。所以最新添加的元素將被最先移除,而且棧中的元素離底端越近,代表其在棧中的時間越長。
這種排序原則被稱作LIFO(last-in first-out
),即后進(jìn)先出。它提供了一種基于在集合中的時間來排序的方式。?最近添加的元素靠近頂端,舊元素則靠近底端。
棧的例子在日常生活中比比皆是。幾乎所有咖啡館都有一個由托盤或盤子構(gòu)成的棧,你可以從頂部取走一個,下一 個顧客則會取走下面的托盤或盤子。
考慮到棧的反轉(zhuǎn)特性,我們可以想到在使用計算機(jī)時的一些例子。例如,每一個瀏覽器都有返回按鈕。當(dāng)我們從一個網(wǎng)頁跳轉(zhuǎn)到另一個網(wǎng)頁時,這些網(wǎng)頁——實際上是URL,都被存放在一個棧中。當(dāng)前正在瀏覽的網(wǎng)頁位于棧的頂端,最早瀏覽的網(wǎng)頁則位于底端。如果點擊返回按鈕, 便開始反向瀏覽這些網(wǎng)頁。
構(gòu)建一個棧
如前所述,棧是元素的有序集合,添加操作與移除操作都發(fā)生在其頂端。棧的操作順序是LIFO,它支持以下操作:
- 將一個元素添加到棧的頂端
- 將棧頂端的元素移除
- 返回棧頂端的元素
- 返回棧中元素的數(shù)目
明確了棧的基本特性之后,我們開始用代碼構(gòu)建它。在面向?qū)ο蟮木幊陶Z言中(以Python為例),每當(dāng)需要在Python中實現(xiàn)像棧這樣的抽象數(shù)據(jù)類型時 ,就可以通過創(chuàng)建一個類的途徑實現(xiàn)它,且數(shù)據(jù)類型的特性、操作方法等也可以通過在類中定義方法實現(xiàn)。
我們來明確一下這個類的具體方法:
- 創(chuàng)建一個空棧。它不需要參數(shù),且會返回一個空棧。 Stack()
- 將一個元素添加到棧的頂端。它需要一 個參數(shù)item?,且無返回值。 push(item)
- 將棧頂端的元素移除。它不需要參數(shù),但會返回頂端的元素,并且修改棧的內(nèi)容。 pop()
- 返回棧頂端的元素,但是并不移除該元素。 它不需要參數(shù),也不會修改棧的內(nèi)容。 peek()
- 返回棧中元素的數(shù)目。它不需要參數(shù),且會返回一個整數(shù)。 size()
- 檢查棧是否為空。它不需要參數(shù),且會返回一個布爾值。 isEmpty()
- 打印這個棧/列表,它不需要參數(shù),會輸出棧的內(nèi)容。 look()
?因為棧是元素的集合,所以完全可以利用Python提供的強(qiáng)大、簡單的原生集合來實現(xiàn)。這里,我們將使用列表。?列表的最左端將用來表示棧底,最右邊將用來表示棧頂:
class Stack: # 定義一個列表/構(gòu)造一個棧 def __init__(self): self.items = [] print("你創(chuàng)造了一個棧!") def isEmpty(self): return self.items == [] def look(self): print(self.items) def push(self, item): self.items.append(item) print("你給棧頂加了個%s" % item) def pop(self): return self.items.pop() def peek(self): return self.items[len(self.items) - 1] def size(self): return len(self.items)
以下展示了棧的操作及其返回結(jié)果:
值得注意的是,也可以選擇將列表的頭部(左邊)作為棧的頂端。 不過在這種情況下,便無法直接使用列表的pop方法和append方法,而必須要用列表的pop方法和insert方法顯式地訪問下標(biāo)為0的元素,即列表中的第1個元素。以下代碼展現(xiàn)了這種方式:
class Stack: def __init__(self): self.items = [] def isEmpty(self): return self.items == [] def look(self): print(self.items) def push(self, item): self.items.insert(0, item) def pop(self): return self.items.pop(0) def peek(self): return self.items[0] def size(self): return len(self.items)
盡管上述兩種實現(xiàn)都可行,但是二者在性能方面肯定有差異。append 方法和 pop 方法的時間復(fù)雜度都是 o ( 1 ) o(1) o(1),這意味著不論棧中有多少個元素, 第一種實現(xiàn)中的 push 操作和 pop 操作都會在恒定的時間內(nèi)完成。第二種實現(xiàn)的性能則受制于棧中的元素個數(shù),這 是因為 insert(0) 和 pop(0) 的時間復(fù)雜度都是 o ( n ) o(n) o(n),元素越多就越慢。
顯而易見,盡管兩種實現(xiàn)在邏輯上是相等的,但是它們在進(jìn)行基準(zhǔn)測試時耗費(fèi)的時間會有很大的差異。
總結(jié)
原文鏈接:https://blog.csdn.net/jiang1126/article/details/123250951
相關(guān)推薦
- 2022-07-17 一起詳細(xì)聊聊C#中的Visitor模式_C#教程
- 2022-03-07 c語言實現(xiàn)學(xué)生管理系統(tǒng)詳解_C 語言
- 2022-09-08 Python報錯SyntaxError:unexpected?EOF?while?parsing的解
- 2024-07-18 Spring Security之基于方法配置權(quán)限
- 2023-02-15 Go語言中節(jié)省內(nèi)存技巧方法示例_Golang
- 2022-07-01 使用Python讀寫多個sheet文件_python
- 2024-03-08 學(xué)習(xí)基于ssm框架前后端分離實現(xiàn)注冊登錄MD5加密的心得體會
- 2023-01-12 C語言求字符串長度的四種方法實例代碼_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支