欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python堆棧的具體使用

 更新時(shí)間:2023年11月10日 15:31:12   作者:Rocky006  
本文主要介紹了Python堆棧的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

概要

雖然一些數(shù)據(jù)結(jié)構(gòu)是通用的并且可以在廣泛的應(yīng)用中使用,但其他數(shù)據(jù)結(jié)構(gòu)是專(zhuān)門(mén)化的并且被設(shè)計(jì)用于處理特定問(wèn)題。堆棧就是這樣一種專(zhuān)門(mén)的結(jié)構(gòu),以其簡(jiǎn)單性和非凡的實(shí)用性而聞名。

那么,什么是棧呢?從本質(zhì)上講,堆棧是一種遵循LIFO(后進(jìn)先出)原則的線性數(shù)據(jù)結(jié)構(gòu)。

多年來(lái),堆棧已經(jīng)在許多領(lǐng)域找到了應(yīng)用,從您最喜歡的編程語(yǔ)言中的內(nèi)存管理到 Web 瀏覽器中的后退按鈕功能。這種內(nèi)在的簡(jiǎn)單性與其廣泛的適用性相結(jié)合,使該堆棧成為開(kāi)發(fā)人員工具庫(kù)中不可或缺的工具。

堆棧數(shù)據(jù)結(jié)構(gòu)的基本概念

從本質(zhì)上講,堆??此坪?jiǎn)單,但它所具有的細(xì)微差別使其在計(jì)算領(lǐng)域具有多種應(yīng)用。在深入研究其實(shí)現(xiàn)和實(shí)際用途之前,讓我們確保對(duì)堆棧的核心概念有一個(gè)透徹的理解。

LIFO(后進(jìn)先出)原則

LIFO是堆棧背后的指導(dǎo)原則。這意味著最后進(jìn)入堆棧的項(xiàng)目是第一個(gè)離開(kāi)的項(xiàng)目。這一特性將堆棧與其他線性數(shù)據(jù)結(jié)構(gòu)(例如隊(duì)列)區(qū)分開(kāi)來(lái)。

注意:另一個(gè)幫助您理解堆棧如何工作的概念的有用示例是想象人們進(jìn)出電梯-最后進(jìn)入電梯的人是第一個(gè)出去的!

基本操作

每個(gè)數(shù)據(jù)結(jié)構(gòu)都是由它支持的操作定義的。對(duì)于堆棧來(lái)說(shuō),這些操作很簡(jiǎn)單但至關(guān)重要:

  • Push - 將一個(gè)元素添加到堆棧頂部。如果堆棧已滿,則此操作可能會(huì)導(dǎo)致堆棧溢出。

dc7d099867f3409483390a34ab3a1405.png

  • Pop - 刪除并返回堆棧最頂層的元素。如果堆棧為空,嘗試彈出可能會(huì)導(dǎo)致堆棧下溢。

0db3bf21927e41b9a1226ccf86da81fd.png

  • Peek(或 Top) - 觀察最上面的元素而不刪除它。當(dāng)您想要檢查當(dāng)前頂部元素而不更改堆棧狀態(tài)時(shí),此操作非常有用。

如何在 Python 中從頭開(kāi)始實(shí)現(xiàn)堆棧

掌握了堆棧背后的基本原理后,是時(shí)候卷起袖子深入研究事物的實(shí)際方面了。實(shí)現(xiàn)堆棧雖然簡(jiǎn)單,但可以通過(guò)多種方式實(shí)現(xiàn)。在本節(jié)中,我們將探討實(shí)現(xiàn)堆棧的兩種主要方法 - 使用數(shù)組和鏈表。

使用數(shù)組實(shí)現(xiàn)堆棧

數(shù)組是連續(xù)的內(nèi)存位置,提供了一種直觀的方式來(lái)表示堆棧。它們?cè)试S按索引訪問(wèn)元素的時(shí)間復(fù)雜度為 O(1),從而確保快速推送、彈出和查看操作。此外,數(shù)組可以提高內(nèi)存效率,因?yàn)闆](méi)有鏈表中的指針開(kāi)銷(xiāo)。

另一方面,傳統(tǒng)數(shù)組具有固定大小,這意味著一旦初始化,它們就無(wú)法調(diào)整大小。如果不進(jìn)行監(jiān)控,這可能會(huì)導(dǎo)致堆棧溢出。這可以通過(guò)動(dòng)態(tài)數(shù)組(如 Python 的list)來(lái)克服,它可以調(diào)整大小,但此操作的成本相當(dāng)高。

完成所有這些后,讓我們開(kāi)始在 Python 中使用數(shù)組實(shí)現(xiàn)我們的堆棧類(lèi)。首先,讓我們創(chuàng)建一個(gè)類(lèi)本身,其構(gòu)造函數(shù)將堆棧的大小作為參數(shù):  ???

class Stack:
    def __init__(self, size):
        self.size = size
        self.stack = [None] * size
        self.top = -1

我們?cè)陬?lèi)中存儲(chǔ)了三個(gè)值。是size所需的堆棧大小,是stack用于表示堆棧數(shù)據(jù)結(jié)構(gòu)的實(shí)際數(shù)組,是數(shù)組中最后一個(gè)元素(堆棧頂部)top的索引。stack

從現(xiàn)在開(kāi)始,我們將為每個(gè)基本堆棧操作創(chuàng)建并解釋一種方法。這些方法中的每一個(gè)都將包含在Stack我們剛剛創(chuàng)建的類(lèi)中。

我們先從push()方法開(kāi)始吧。如前所述,入棧操作將一個(gè)元素添加到堆棧頂部。首先,我們將檢查堆棧是否還有空間供我們要添加的元素使用。如果堆棧已滿,我們將引發(fā)Stack Overflow異常。否則,我們只需添加元素并相應(yīng)地調(diào)整top和stack: ?????

def push(self, item):
        if self.top == self.size - 1:
            raise Exception("Stack Overflow")
        self.top += 1
        self.stack[self.top] = item

現(xiàn)在,我們可以定義從棧頂移除元素的方法——方法pop()。在嘗試刪除元素之前,我們需要檢查堆棧中是否有任何元素,因?yàn)閲L試從空堆棧中彈出元素是沒(méi)有意義的: ????

def pop(self):
        if self.top == -1:
            raise Exception("Stack Underflow")
        item = self.stack[self.top]
        self.top -= 1
        return item

最后,我們可以定義peek()只返回當(dāng)前堆棧頂部元素的值的方法: ??????

def peek(self):
    if self.top == -1:
        raise Exception("Stack is empty")
    return self.stack[self.top]

我們現(xiàn)在有一個(gè)類(lèi),它在 Python 中使用列表實(shí)現(xiàn)堆棧的行為。

使用鏈表實(shí)現(xiàn)堆棧

鏈表是動(dòng)態(tài)數(shù)據(jù)結(jié)構(gòu),可以輕松增長(zhǎng)和收縮,這對(duì)于實(shí)現(xiàn)堆棧是有利的。由于鏈表根據(jù)需要分配內(nèi)存,因此堆??梢詣?dòng)態(tài)增長(zhǎng)和減少,而無(wú)需顯式調(diào)整大小。使用鏈表實(shí)現(xiàn)堆棧的另一個(gè)好處是入棧和出棧操作只需要簡(jiǎn)單的指針變化。這樣做的缺點(diǎn)是鏈表中的每個(gè)元素都有一個(gè)額外的指針,與數(shù)組相比會(huì)消耗更多的內(nèi)存。

在實(shí)際鏈表之前我們需要實(shí)現(xiàn)的第一件事是單個(gè)節(jié)點(diǎn)的類(lèi): ?????

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

此實(shí)現(xiàn)僅存儲(chǔ)兩點(diǎn)數(shù)據(jù) - 存儲(chǔ)在節(jié)點(diǎn) ( ) 中的值data和對(duì)下一個(gè)節(jié)點(diǎn) ( ) 的引用next。

現(xiàn)在我們可以跳到實(shí)際的堆棧類(lèi)本身。構(gòu)造函數(shù)與之前的構(gòu)造函數(shù)略有不同。它將只包含一個(gè)變量 - 對(duì)堆棧頂部節(jié)點(diǎn)的引用: ??????

class Stack:
    def __init__(self):
        self.top = None

正如預(yù)期的那樣,該push()方法將一個(gè)新元素(在本例中為節(jié)點(diǎn))添加到堆棧頂部: ??????

def push(self, item):
        node = Node(item)
        if self.top:
            node.next = self.top
        self.top = node

該pop()方法檢查堆棧中是否有元素,如果堆棧不為空,則刪除最上面的元素: ??????

def pop(self):
        if not self.top:
            raise Exception("Stack Underflow")
        item = self.top.data
        self.top = self.top.next
        return item

最后,該peek()方法只是從堆棧頂部讀取元素的值(如果有的話): ????

def peek(self):
    if not self.top:
        raise Exception("Stack is empty")
    return self.top.data

注意:兩個(gè)類(lèi)的接口Stack是相同的 - 唯一的區(qū)別是類(lèi)方法的內(nèi)部實(shí)現(xiàn)。這意味著您可以輕松地在不同的實(shí)現(xiàn)之間切換,而不必?fù)?dān)心類(lèi)的內(nèi)部結(jié)構(gòu)。

數(shù)組和鏈表之間的選擇取決于應(yīng)用程序的具體要求和約束。

如何使用 Python 的內(nèi)置結(jié)構(gòu)實(shí)現(xiàn)堆棧

對(duì)于許多開(kāi)發(fā)人員來(lái)說(shuō),從頭開(kāi)始構(gòu)建堆棧雖然具有教育意義,但可能不是在實(shí)際應(yīng)用程序中使用堆棧的最有效方法。幸運(yùn)的是,許多流行的編程語(yǔ)言都配備了自然支持堆棧操作的內(nèi)置數(shù)據(jù)結(jié)構(gòu)和類(lèi)。

Python 作為一種多功能且動(dòng)態(tài)的語(yǔ)言,沒(méi)有專(zhuān)用的堆棧類(lèi)。然而,它的內(nèi)置數(shù)據(jù)結(jié)構(gòu),特別是模塊中的列表和雙端隊(duì)列類(lèi)collections,可以輕松地用作堆棧。

使用 Python 列表作為堆棧

append()由于 Python 列表的動(dòng)態(tài)特性以及和 等方法的存在,Python 列表可以非常有效地模擬堆棧pop()。

  • 推送操作- 將元素添加到堆棧頂部就像使用以下append()方法一樣簡(jiǎn)單:

  • stack = []
    stack.append('A')
    stack.append('B')
  • Pop 操作- 刪除最上面的元素可以使用不帶任何參數(shù)的方法來(lái)實(shí)現(xiàn)pop():

  • top_element = stack.pop()  # This will remove 'B' from the stack
  • 窺視操作可以使用負(fù)索引來(lái)訪問(wèn)頂部而不彈出:

  • top_element = stack[-1]  # This will return 'A' without removing it

使用集合模塊中的deque類(lèi)

deque(雙端隊(duì)列的縮寫(xiě))類(lèi)是堆棧實(shí)現(xiàn)的另一個(gè)多功能工具。它針對(duì)兩端的快速追加和彈出進(jìn)行了優(yōu)化,使其堆棧操作比列表稍微高效一些。

  • 初始化:

  • from collections import deque
    stack = deque()
  • 推送操作- 與列表類(lèi)似,append()使用方法:

  • stack.append('A')
    stack.append('B')
  • 彈出操作- 與列表類(lèi)似,pop()方法執(zhí)行以下工作:

  • top_element = stack.pop()  # This will remove 'B' from the stack
  • 查看操作- 方法與列表相同:

top_element = stack[-1]  # This will return 'A' without removing it
  • 雖然列表和雙端隊(duì)列都可以用作堆棧,但如果您主要將結(jié)構(gòu)用作堆棧(從一端追加和彈出),由于deque其優(yōu)化,速度可能會(huì)稍快一些。

  • 然而,對(duì)于大多數(shù)實(shí)際目的,除非處理性能關(guān)鍵的應(yīng)用程序,Python 的列表應(yīng)該足夠了。

注意:本節(jié)深入探討 Python 的類(lèi)似堆棧行為的內(nèi)置產(chǎn)品。當(dāng)您手邊擁有如此強(qiáng)大的工具時(shí),您不一定需要重新發(fā)明輪子(通過(guò)從頭開(kāi)始實(shí)現(xiàn)堆棧)。

堆棧潛在的相關(guān)問(wèn)題以及如何克服它們

雖然堆棧像任何其他數(shù)據(jù)結(jié)構(gòu)一樣具有令人難以置信的通用性和高效性,但它們也不能避免潛在的陷阱。在使用堆棧時(shí)必須認(rèn)識(shí)到這些挑戰(zhàn)并制定解決這些挑戰(zhàn)的策略。在本節(jié)中,我們將深入探討一些常見(jiàn)的堆棧相關(guān)問(wèn)題,并探索解決這些問(wèn)題的方法。

堆棧溢出

當(dāng)嘗試將元素推入已達(dá)到其最大容量的堆棧時(shí),就會(huì)發(fā)生這種情況。在堆棧大小固定的環(huán)境中(例如在某些低級(jí)編程場(chǎng)景或遞歸函數(shù)調(diào)用中),這尤其是一個(gè)問(wèn)題。

如果使用基于數(shù)組的堆棧,請(qǐng)考慮切換到動(dòng)態(tài)數(shù)組或鏈表實(shí)現(xiàn),它們會(huì)自行調(diào)整大小。防止堆棧溢出的另一個(gè)步驟是持續(xù)監(jiān)視堆棧的大小,特別是在壓入操作之前,并針對(duì)堆棧溢出提供明確的錯(cuò)誤消息或提示。

如果由于過(guò)多的遞歸調(diào)用而導(dǎo)致堆棧溢出,請(qǐng)考慮迭代解決方案或在環(huán)境允許的情況下增加遞歸限制。

堆棧下溢

當(dāng)嘗試從空堆棧中彈出元素時(shí)會(huì)發(fā)生這種情況。為了防止這種情況發(fā)生,請(qǐng)?jiān)趫?zhí)行彈出或查看操作之前始終檢查堆棧是否為空。返回清晰的錯(cuò)誤消息或優(yōu)雅地處理下溢,而不會(huì)導(dǎo)致程序崩潰。

在可接受的環(huán)境中,請(qǐng)考慮在從空堆棧彈出時(shí)返回一個(gè)特殊值以表示操作無(wú)效。

內(nèi)存限制

在內(nèi)存受限的環(huán)境中,即使動(dòng)態(tài)調(diào)整堆棧大?。ɡ缁阪湵淼亩褩#?,如果堆棧變得太大,也可能會(huì)導(dǎo)致內(nèi)存耗盡。因此,請(qǐng)密切關(guān)注應(yīng)用程序的整體內(nèi)存使用情況和堆棧的增長(zhǎng)。也許對(duì)堆棧的大小引入軟上限。

線程安全問(wèn)題

在多線程環(huán)境中,不同線程對(duì)共享堆棧的同時(shí)操作可能會(huì)導(dǎo)致數(shù)據(jù)不一致或意外行為。此問(wèn)題的潛在解決方案可能是:

  • 互斥體和鎖- 使用互斥體(互斥對(duì)象)或鎖來(lái)確保在給定時(shí)間只有一個(gè)線程可以在堆棧上執(zhí)行操作。

  • 原子操作- 如果環(huán)境支持,則利用原子操作來(lái)確保推送和彈出操作期間的數(shù)據(jù)一致性。

  • 線程本地堆棧- 在每個(gè)線程都需要其堆棧的情況下,請(qǐng)考慮使用線程本地存儲(chǔ)為每個(gè)線程提供單獨(dú)的堆棧實(shí)例。

總結(jié)

雖然堆棧確實(shí)很強(qiáng)大,但了解其潛在問(wèn)題并積極實(shí)施解決方案將確保應(yīng)用程序的健壯和無(wú)錯(cuò)誤。認(rèn)識(shí)到這些陷阱就成功了一半,另一半就是采用最佳實(shí)踐來(lái)有效解決這些問(wèn)題。

到此這篇關(guān)于Python堆棧的具體使用的文章就介紹到這了,更多相關(guān)Python堆棧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決Python下imread,imwrite不支持中文的問(wèn)題

    解決Python下imread,imwrite不支持中文的問(wèn)題

    今天小編就為大家分享一篇解決Python下imread,imwrite不支持中文的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • python插入排序算法實(shí)例分析

    python插入排序算法實(shí)例分析

    這篇文章主要介紹了python插入排序算法,通過(guò)兩個(gè)簡(jiǎn)單實(shí)例對(duì)比分析了Python插入排序算法的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-07-07
  • python flask框架快速入門(mén)

    python flask框架快速入門(mén)

    Flask 本身相當(dāng)于一個(gè)內(nèi)核,其他幾乎所有的功能都要用到擴(kuò)展,都需要用第三方的擴(kuò)展來(lái)實(shí)現(xiàn),本文給大家分享如何快速入門(mén)python flask框架,感興趣的朋友一起看看吧
    2021-05-05
  • python使用wxpython開(kāi)發(fā)簡(jiǎn)單記事本的方法

    python使用wxpython開(kāi)發(fā)簡(jiǎn)單記事本的方法

    這篇文章主要介紹了python使用wxpython開(kāi)發(fā)簡(jiǎn)單記事本的方法,涉及Python使用wxPython實(shí)現(xiàn)桌面圖形應(yīng)用程序的技巧,需要的朋友可以參考下
    2015-05-05
  • python中json.dumps和json.dump區(qū)別

    python中json.dumps和json.dump區(qū)別

    json.dumps將Python對(duì)象序列化為JSON字符串,json.dump直接將Python對(duì)象序列化寫(xiě)入文件,本文就來(lái)介紹一下兩個(gè)的使用及區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-12-12
  • Python適配器模式代碼實(shí)現(xiàn)解析

    Python適配器模式代碼實(shí)現(xiàn)解析

    這篇文章主要介紹了Python適配器模式代碼實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • pandas?dataframe按照列名給列排序三種方法

    pandas?dataframe按照列名給列排序三種方法

    這篇文章主要給大家介紹了關(guān)于pandas?dataframe按照列名給列排序的三種方法,在進(jìn)行數(shù)據(jù)分析操作時(shí),經(jīng)常需要對(duì)數(shù)據(jù)按照某行某列排序,或者按照多行多列排序,以及按照索引值排序等等,需要的朋友可以參考下
    2023-07-07
  • Python定時(shí)執(zhí)行程序問(wèn)題(schedule)

    Python定時(shí)執(zhí)行程序問(wèn)題(schedule)

    這篇文章主要介紹了Python定時(shí)執(zhí)行程序問(wèn)題(schedule),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • python利用cv2庫(kù)讀取和保存視頻的操作步驟

    python利用cv2庫(kù)讀取和保存視頻的操作步驟

    這篇文章主要介紹了python利用cv2庫(kù)讀取和保存視頻的操作步驟,文中通過(guò)代碼示例給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-04-04
  • jupyter閃退怎么辦?jupyter閃退問(wèn)題的解決

    jupyter閃退怎么辦?jupyter閃退問(wèn)題的解決

    這篇文章主要介紹了jupyter閃退怎么辦?jupyter閃退問(wèn)題的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01

最新評(píng)論