《數(shù)據(jù)結(jié)構(gòu)與算法之美》- 棧

棧蔫饰,在這里說的是一種數(shù)據(jù)結(jié)構(gòu)。

你還可能知道的棧

提到“椨洳颍”篓吁,做Java的同學(xué)還會(huì)想起Java內(nèi)存模型中的“棧”蚪拦,與之緊密關(guān)聯(lián)的還有一個(gè)名詞——堆杖剪,但是這里,此棧非彼棧驰贷。

引用《深入理解Java虛擬機(jī)》中有關(guān)棧的介紹

經(jīng)常有人把Java內(nèi)存區(qū)分為堆內(nèi)存(Heap)和棧內(nèi)存(Stack)盛嘿,這種分法比較粗糙,Java內(nèi)存區(qū)域的劃分實(shí)際上遠(yuǎn)比這復(fù)雜括袒。這種劃分方式的流行只能說明大多數(shù)程序員最關(guān)注的次兆、與對(duì)象內(nèi)存分配關(guān)系最密切的內(nèi)存區(qū)域是這兩塊。其中所指的“堆”筆者在后面專門講述箱熬,而所指的“椑嗫眩”就是現(xiàn)在講的虛擬機(jī)棧,或者說是虛擬機(jī)棧中局部變量部分城须。

局部變量表存放了編譯可知的各種基本數(shù)據(jù)類型(boolean蚤认、byte、char糕伐、short砰琢、int、float良瞧、long陪汽、double)、對(duì)象引用(reference類型褥蚯,它不等同于對(duì)象本身挚冤,可能是一個(gè)只想對(duì)象起始地址的引用指針,也可能是指向一個(gè)對(duì)象的句柄或其他與此對(duì)象相關(guān)的位置)和returnAddress類型(指向了一條字節(jié)碼指令的地址)

說人話就是赞庶,Java內(nèi)存結(jié)構(gòu)中的一部分训挡,線程私有澳骤,用來(lái)存儲(chǔ)指定的數(shù)據(jù)類型數(shù)據(jù)。

棧是什么

棧是一種數(shù)據(jù)結(jié)構(gòu)澜薄,它有自己的特點(diǎn)

  • 它是一種線性表为肮,同為線性表的還有之前說到的數(shù)組和鏈表

  • 它操作受限,具體表現(xiàn)在先進(jìn)后出肤京,后進(jìn)先出颊艳,只能在一端進(jìn)行數(shù)據(jù)的插入和刪除

基于以上兩點(diǎn),大概就能勾勒出棧的模樣忘分。

image.png

棧的應(yīng)用

經(jīng)常聽到有很多人抱怨說(也包括我~~~)棋枕,如果知道這門課這么重要,我當(dāng)時(shí)拼死老命也要把它學(xué)好饭庞。

還記得當(dāng)時(shí)看吳恩達(dá)的《machine learning》戒悠,在前幾節(jié)課里展示了如何使用聚類算法進(jìn)行圖像處理,如果使用增強(qiáng)學(xué)習(xí)算法讓一個(gè)模型飛機(jī)飛起來(lái)

image.png
image.png

那么舟山,我們來(lái)看下棧有什么應(yīng)用

棧在表達(dá)式求值中的應(yīng)用

給出一個(gè)表達(dá)式“3+5*8-6”,如果讓你算卤恳,想必難不倒你累盗。

交給機(jī)器做,肯定也難不倒它突琳,機(jī)器甚至可以做更加復(fù)雜的你做不到的運(yùn)算若债。

但是機(jī)器底層是怎么做的,如果不給定規(guī)則拆融,它并不知道加減乘除是什么蠢琳,也不知道他們的優(yōu)先級(jí)順序。所以镜豹,這時(shí)候棧就排上了用場(chǎng)傲须。

具體做法:

準(zhǔn)備兩個(gè)棧,一個(gè)用來(lái)存儲(chǔ)需要運(yùn)算的數(shù)字趟脂,一個(gè)用來(lái)存儲(chǔ)運(yùn)算符號(hào)泰讽。

數(shù)字棧按照從左到右的順序入棧,符號(hào)棧也是如此昔期,只是除此之外還多了一個(gè)規(guī)則限定已卸。

當(dāng)新入棧的符號(hào)優(yōu)先級(jí)比當(dāng)前棧頂符號(hào)的優(yōu)先級(jí)高的時(shí)候,繼續(xù)入棧硼一;當(dāng)比棧頂符號(hào)優(yōu)先級(jí)低或者相同時(shí)累澡,則取出當(dāng)前棧頂符號(hào),同時(shí)取出數(shù)字棧的操作數(shù)字進(jìn)行運(yùn)算般贼,將運(yùn)算后的結(jié)果壓棧愧哟,直至兩個(gè)棧元素全部彈出惑申。

具體看專題中給出的過程圖

image.png

棧在括號(hào)匹配中的應(yīng)用

給出一串“{(({[{{}}]}))}”,需要校驗(yàn)這串表達(dá)式中是否能前后一一匹配翅雏。

沒錯(cuò)圈驼,這個(gè)也可以利用棧的特性解決。

具體做法:

從左到右掃描表達(dá)式望几,對(duì)于左括號(hào)入棧绩脆,遇到右括號(hào)則取出當(dāng)前棧頂元素,如果發(fā)現(xiàn)匹配橄抹,則取出棧頂元素繼續(xù)匹配靴迫。

當(dāng)所有字符串匹配完成,并且棧最后是空棧楼誓,說明字符串可以正確匹配玉锌。

棧在瀏覽器前進(jìn)后退中的應(yīng)用

在瀏覽器中,我們可以通過前進(jìn)后退回到自己想要的網(wǎng)頁(yè)疟羹。

這個(gè)功能也是可以通過棧來(lái)實(shí)現(xiàn)的主守,具體做法:

準(zhǔn)備兩個(gè)棧,一個(gè)用于存放前進(jìn)棧的網(wǎng)頁(yè)ID榄融,一個(gè)用于存放后退棧的網(wǎng)頁(yè)ID参淫。當(dāng)需要前進(jìn)的時(shí)候,從前進(jìn)棧取出棧頂元素愧杯,并將該元素放入后退棧中涎才;

當(dāng)需要后退的時(shí)候,從后退棧取出棧頂元素力九,并將該元素放入前進(jìn)棧中耍铜。

具體實(shí)現(xiàn)參見項(xiàng)目rome中的BackAndForwardUtil和BackAndForwardUtilDemo類

如何實(shí)現(xiàn)一個(gè)棧

采用鏈表接口實(shí)現(xiàn)一個(gè)棧結(jié)構(gòu)


package com.jackie.algo.geek.time.chapter8_stack;

/**
 * @Author: Jackie
 */
public class Stack {
    private Node top = null;

    /**
     * 壓棧
     * @see com.jackie.algo.geek.time.chapter6_linkedlist.LinkedList 中的insertToHead方法和這里的push思想類似
     *
     * |------|
     * | node | 上移后的top在這個(gè)位置
     * |------|
     * |   p  | 一開始top在這里,經(jīng)過node.next = top綁定了node和p關(guān)系后跌前,又通過top = node棕兼,則將top上移
     * |------|
     * |  ... |
     * |------|
     *
     */
    public void push(int value) {
        Node node = new Node(value, null);

        if (top == null) {
            top = node;
        } else {
            node.next = top;
            top = node;
        }
    }
    /**
     * 出棧
     */
    public int pop() {
        if (top == null) {
            return -1;
        }
        int value = top.value;
        top = top.next;

        return value;
    }
    public void printAll() {
        Node p = top;
        while (p != null) {
            System.out.print(p.value + " ");
            p = p.next;
        }
        System.out.println();
    }
    public static class Node {
        private int value;

        private Node next;

        public Node(int value, Node next) {
            this.value = value;
            this.next = next;
        }
    }
}

具體參見項(xiàng)目rome

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市舒萎,隨后出現(xiàn)的幾起案子程储,更是在濱河造成了極大的恐慌,老刑警劉巖臂寝,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件章鲤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡咆贬,警方通過查閱死者的電腦和手機(jī)败徊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)掏缎,“玉大人皱蹦,你說我怎么就攤上這事煤杀。” “怎么了沪哺?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵沈自,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我辜妓,道長(zhǎng)枯途,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任籍滴,我火速辦了婚禮酪夷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘孽惰。我一直安慰自己晚岭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布勋功。 她就那樣靜靜地躺著坦报,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酝润。 梳的紋絲不亂的頭發(fā)上燎竖,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音要销,去河邊找鬼。 笑死夏块,一個(gè)胖子當(dāng)著我的面吹牛疏咐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脐供,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼浑塞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了政己?” 一聲冷哼從身側(cè)響起酌壕,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎歇由,沒想到半個(gè)月后卵牍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沦泌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年糊昙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谢谦。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡释牺,死狀恐怖萝衩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情没咙,我是刑警寧澤猩谊,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站祭刚,受9級(jí)特大地震影響牌捷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜袁梗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一宜鸯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧遮怜,春花似錦淋袖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至陌凳,卻和暖如春剥懒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背合敦。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工初橘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人充岛。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓保檐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親崔梗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子夜只,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 1)這本書為什么值得看: Python語(yǔ)言描述,如果學(xué)的Python用這本書學(xué)數(shù)據(jù)結(jié)構(gòu)更合適 2016年出版蒜魄,內(nèi)容...
    孫懷闊閱讀 12,466評(píng)論 0 15
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,097評(píng)論 1 32
  • 且行且影閱讀 954評(píng)論 9 37
  • 常擔(dān)心別人看到自己的缺點(diǎn)扔亥,比如發(fā)現(xiàn)自己不夠聰明,經(jīng)過思考發(fā)現(xiàn)谈为,擔(dān)心有什么用呢旅挤?還不如坦然面對(duì)現(xiàn)實(shí),承認(rèn)自己的缺點(diǎn)峦阁。...
    紹波_2c77閱讀 219評(píng)論 0 0
  • 快速挽回瘪菌?你們分手也是很快速的嗎? 對(duì)待愛情就像玩游戲一樣嘹朗,草率师妙,簡(jiǎn)單,想放棄就放棄了屹培。后悔了默穴,勾勾手指,就又和好...
    眉目成書閱讀 169評(píng)論 0 0