1. 程式人生 > >程式設計師,你應該知道的資料結構之棧

程式設計師,你應該知道的資料結構之棧

資料結構中的棧不要與 Java 中的棧混淆,他們倆不是一回事,資料結構中的棧是一種受限制的線性表,棧具有先進後出、後進先出的特點,因為棧只允許訪問最後一個數據項,即最後插入的資料項。也許你會有疑問,棧既然有這麼多限制,為什麼不用陣列或者連結串列而使用棧?在開發中,我們有特定的場景,根據特定的場景去選用資料結構,棧的適用場景非常多,比如瀏覽器的前進與後退、字串括號的合法性等,我們使用棧來實現就比較好,因為棧相對陣列、連結串列來說對外提供的介面要少很多,介面少了,出錯的概率就減少了,對風險的可控性就提高了。

實現一個棧

從棧的定義中可以看出,棧主要有兩個操作,一個是新增一條資料,我們叫做入棧,另一個是獲取一條資料,稱為出棧,下面兩張圖是入棧出棧示意圖。


棧的實現有兩種方式,一種是基於陣列實現的,我們叫作順序棧,另一種是基於連結串列實現的,我們叫作鏈式棧。下面是兩種棧的實現程式碼

基於陣列的順序棧

/**
 * 基於陣列的順序棧
 */
public class ArrayStack {

    // 棧最大容量
    private int maxSzie;
    // 存放內容
    private String[] array;
    // 棧頂元素
    private int top;

    public ArrayStack(int size){
        this.maxSzie = size;
        this.array = new String[this.maxSzie];
        this.top = 0;
    }

    /**
     * 入棧操作
     *
     * @param data 資料
     * @return 0:入棧失敗 1:入棧成功
     */
    public int push(String data) {
        if (top == maxSzie) return 0;
        array[top] = data;
        top++;
        return 1;
    }

    /**
     * 出棧操作
     *
     * @return
     */
    public String pop() {
        if (top == 0) return null;
        return array[--top];
    }

    /**
     * 獲取棧頂元素
     *
     * @return
     */
    public String peek() {
        return array[top - 1];
    }
    /**
     * 判斷棧是否為空
     * @return
     */
    public boolean isEmpty() {
        return top == 0;
    }
}

基於連結串列的鏈式棧

/**
 * 基於連結串列的鏈式棧
 */
public class LinkStack {

    // 始終指向棧的第一個元素
    private Node top = null;


    /**
     * 壓棧
     *
     * @param data
     * @return
     */
    public int push(String data) {
        Node node = new Node(data);
        if (top == null) {
            top = node;
        } else {
            node.next = top;
            top = node;
        }
        return 1;
    }


    /**
     * 出棧
     *
     * @return
     */
    public String pop() {
        if (top == null) return null;
        String data = top.getData();
        top = top.next;
        return data;
    }

    /**
     * 節點資訊
     */
    private static class Node {
        private String data;
        private Node next;

        public Node(String data) {
            this.data = data;
            this.next = null;
        }

        public String getData() {
            return this.data;
        }
    }
}

棧的實現比較簡單,因為棧涉及的操作不多,主要就入棧和出棧兩個操作。

棧的應用

檢測字串括號的合法性

我們有時候需要檢測字串括號的合法性,即一個左括號需要匹配一個右括號,這個我們可以使用棧來實現。我們可以從一個合法的括號來理解為什麼使用棧?如果括號使用合法,最後一個左括號跟第一個右括號是匹配的,倒數第二個左括號和第二個右括號匹配的,以此類推,這符合我們棧的特性先進後出。

假設我們有三種括號:圓括號 ()、方括號 [] 和花括號{},我們使用棧來檢測括號的合法性。我們將左括號全部壓棧,當出現右括號時,我們就進行匹配,這時候有如下三種情況:

  • 棧為空,說明沒有左括號,括號使用不合法
  • 棧中取出來的左括號跟右括號不匹配,括號使用不合法
  • 棧中取出的左括號跟右括號匹配,括號使用暫時合法

當整個字串都掃描完成後,檢測棧中是否還有值,如果棧為空,則說明括號使用合法,反正,則括號使用不合法。

實現程式碼

public static boolean BracketChecker(String data) {
    char[] chars = data.toCharArray();
    ArrayStack stack = new ArrayStack(chars.length);
    for (char ch : chars) {
        switch (ch){
            case '{':
            case '[':
            case '(':
                stack.push(ch);
                break;
            case '}':
            case ']':
            case ')':
                if (!stack.isEmpty()){
                    char ch1 = stack.pop();
                    if ((ch=='}' && ch1 !='{')
                        ||(ch==']' && ch1 !='[')
                        ||(ch==')' && ch1 !='(')

                    ){
                        return false;
                    }
                }else {
                    return false;
                }

                break;
            default:
                break;
        }

    }
    return stack.isEmpty();
}

瀏覽器前進、後退功能

我們使用瀏覽器都知道,瀏覽器可以前進、後退功能,瀏覽器的前進後退也符合棧的特點,我們最先訪問的網頁肯定要最後才能倒回去。我們一起來看看棧怎麼實現這個功能?

我們需要定義兩個棧,我們將首次訪問的頁面壓棧到第一個棧中,當點選後退時,從第一個棧中取出資料放入到第二個棧,當點選前進按鈕時,從第二個棧取出資料放入第一個棧。當第一個棧沒有資料時,說明沒有頁面可以點選後退了,當第二個棧沒有資料時,說明沒有頁面可以點選前進了。這樣我們就通過棧實現了瀏覽器前進、後退功能。

最後

打個小廣告,金九銀十跳槽季,平頭哥給大家整理了一份較全面的 Java 學習資料,歡迎掃碼關注微信公眾號:「平頭哥的技術博文」領取,祝各位升職加薪。

相關推薦

程式設計師應該知道資料結構跳錶

跳錶的原理 跳錶也叫跳躍表,是一種動態的資料結構。如果我們需要在有序連結串列中進行查詢某個值,需要遍歷整個連結串列,二分查詢對連結串列不支援,二分查詢的底層要求為陣列,遍歷整個連結串列的時間複雜度為O(n)。我們可以把連結串列改造成B樹、紅黑樹、AVL樹等資料結構來提升查詢效率,但是B樹、紅黑樹、AVL樹這些

程式設計師應該知道資料結構雜湊表

雜湊表簡介 雜湊表也叫散列表,雜湊表是一種資料結構,它提供了快速的插入操作和查詢操作,無論雜湊表總中有多少條資料,插入和查詢的時間複雜度都是為O(1),因為雜湊表的查詢速度非常快,所以在很多程式中都有使用雜湊表,例如拼音檢查器。 雜湊表也有自己的缺點,雜湊表是基於陣列的,我們知道陣列建立後擴容成本比較高,所以

程式設計師應該知道資料結構

資料結構中的棧不要與 Java 中的棧混淆,他們倆不是一回事,資料結構中的棧是一種受限制的線性表,棧具有先進後出、後進先出的特點,因為棧只允許訪問最後一個數據項,即最後插入的資料項。也許你會有疑問,棧既然有這麼多限制,為什麼不用陣列或者連結串列而使用棧?在開發中,我們有特定的場景,根據特定的場景去選用資料結構

Python程式設計師必須知道的面試題

Python越來越火之後,把python作為自己的終生事業來做的話,是很多的終極目標,可是要做到知己知彼,百戰不殆,那麼你需要了解面試官出什麼題, 這些面試問題大致可以分為四類:什麼(what)?如何做(how)?說區別/談優勢(difference)以及實踐操作(practice)。 &n

一個優秀的java程式設計師需要知道的10個程式碼優化方式!

程式碼優化不息以來都是一個軌範員經常要掛在嘴邊的一個詞,特別是對付如今軌範員越來越普及,網上教程一大把的時代,良多軌範員寫出的程式碼都是為了了局而寫程式碼,從來不去考慮程式碼的優化問題,如許的程式碼拿去應聘也是非常虧損的,程式碼的優化可以直接浮現出來一個軌範員的根基功以及可塑性. 而程式碼

#女生為什麼都要嫁給程式設計師看看程式設計師薪資知道了!

很多女生都喜歡嫁給程式設計師,聽她們說,程式設計師工資高,人好。程式設計師這個行業的薪資高我想大家都是聽說過的,但是大家一直都不知道一個明確的數,作為程式設計師,他們在百度,阿里巴巴,騰訊的工資是怎麼樣的呢?到底有多高?據媒體報道,總結了BAT程式設計師工資的統

關於 Token應該知道的十件事

敏感信息 you load 冒充 tro hex 服務器 xhr cors 轉自:http://ju.outofmemory.cn/entry/134189 原文是一篇很好的講述 Token 在 Web 應用中使用的文章,而這是我和 Special 合作翻譯的譯文。 1.

做網站SEO優化這些網絡引流方法應該知道

尋求 可能 垃圾郵件 百度搜 如果 什麽 網站鏈接 很快 建立 對於網站SEO優化來說,網站流量的重要性不言而喻!國內的站長平臺工具通過用網站流量來衡量一個網站的權重,當你的網站流量很高的時候,同時會影響你網站的權重,進而影響你網站SEO優化排名。所以說流量對於一個網站的意

Select 使用不當引發的core應該知道

retcode 代碼 async fetch sse com 基礎 -a cnblogs 排查一個死機問題,搞了好幾天時間,最終確定原因;最終確定問題原因,在此分享一下; 第一步:常規根據core文件查看棧信息,gdb –c core xxxx 如下rip不正確,指令地址錯

程式設計師焦慮嗎?

我很焦慮,請問程式設計師們,你焦慮嗎? 我是一名年過30的北漂程式設計師,我身邊的朋友大多也是程式設計師。我總感覺到30歲以上的程式設計師充滿了焦慮。“華為清退35歲以上老員工”、“中興程式設計師墜樓”這些事件,更加重了程式設計師的焦慮。 最近又有朋友都跟我抱怨他們的焦慮的事情,我仔細聽完後發現,他們焦慮

程式設計師焦慮嗎有感。

話說在部落格看到一篇文章,說三十出頭的程式設計師很焦慮。是的,很焦慮啊,誰不焦慮啊,難道只有程式設計師這行才焦慮嗎?其實,並不是,而是窮人在一線城市都焦慮,特別是拖家帶口的,家裡頂樑柱的,這世界只有一種病,就是窮病嘛。 話說回來,這程式設計師怎麼就那麼窮呢?我的看法有下幾點。 1,上班再忙,也要按時吃飯和

五種型別的程式設計師屬於哪一種?

在我的程式設計生涯中,我碰到過很多奇奇怪怪的對手和同盟。我把這些編碼戰士們分成五類,有些人是你隊伍中的好夥伴,有些人則是搗蛋者,讓你的每一個計劃都完不成。 不管怎麼說,他們在軟體開發的諸神殿上都佔有一席之地。如果你的團隊中沒有一個合適健康的比例,混合這些不同型別的程式設計師,要麼你會發現你的專案跌跌

要當程式設計師首先得了解的大腦!戒掉遊戲!

把大腦當做第三個人,他會不聽話,分泌多巴胺去玩遊戲。 讓你根本沒有心思去學習! 所以,瞭解和控制你的大腦是必須的! 幾年前,我在一次學術會議上碰到一位漂亮的女孩。交流之後,發現我們有著相似的興趣、相近的背景、隔得不遠。我們在會議期間聊的非常投機,會議之後也保持著聯絡,交往越來越多。彼時的我,

程式設計師碰到過的最難調的Bug是什麼樣的?

Bug無論是對於測試還是開發來說,應該都不陌生,雖然我們經歷的大部分bug有的被其他人修復了並且在網際網路分享出來了,這時候我們通過Stackoverflow、Baidu、Google等搜尋引擎找到答案了。   但是我們在工作中也可能會遇到一些疑難的bug,這裡bug我們在搜素引擎

作為程式設計師“怕老”嗎?

行文之前,先問大家幾個問題: 1,你開始逐漸擔憂自己的年紀? 2,你開始覺得加班熬不過小年輕? 3,你開始因未知新興技術而慌張? 4,你開始跳不動槽? 如果以上的回答都“是”,那麼你確實陷入“怕老”行列了。 “青春飯”這個詞,程式設計師肯定不陌生,因為上了幾年班,做到一

【1024程式設計師節】程式設計師學程式設計的初衷是什麼?

前言 今天是1024程式設計師節,中國500w+的程式設計師今天可以享受一天專屬的節日,網路上也有各種慶祝方式: 一些公司祭出了“程式設計師鼓勵師” 一些公司給程式設計師放了個“假” 還有公司出了張“海報” 都是玩

精準鑑別初級、中級、高階程式設計師是哪一種?

@jonde 初級:產品是大爺 中級:懟過產品 高階:打過產品   @PureWhiteWu  初級:加班 中級:不加班 高階:你們加班   @sunsulei 初級:嗯? 中級:嗯。 高階:嗯?

作為UI設計師知道的那些事兒

我們常用“白紙黑字”來表示一種顯而易見的事實,因為白色背景搭配黑色文字,可讀性是最佳的。許多UI設計師在選擇配色方案的時候,會更自覺地傾向淺色、明亮的背景和深色的文字。 不過,設計從來都不是一種囿於條條框框之中“循規蹈矩”的工作,許多 UI介面的設計並沒有一直遵循這種“白紙黑字”的規律。一方

作為程式設計師在程式設計時吃了哪些數學的虧?

“如果,你只想當個普通程式設計師,數學對你來說並不重要;但你要想做頂級程式設計師,數學對你來說就相當重要了。”這是幾年前我在矽谷技術交流 Meetup 上聽到的一個分享,而在聽到這番話之前,我很少思考數學和計算機程式設計之間的關係。 這二者之間的關係,到底有多緊密呢?我們可以從 Goo

關於首個受監管的穩定幣GUSD應該知道這些真相

今天早上,美國交易所 Gemini 和另外一個區塊鏈創業公司 Paxos 同時獲得了美國紐約金融服務局的批准,可以在受政府監管的情況下發行錨定美元的數字加密貨幣 GUSD 和 PAX。這種與美元掛鉤而且可以與美元進行直接兌換的數字加密貨幣在區塊鏈行業中有不少先例,比如我們熟悉