摘要:棧也稱為后進(jìn)先出表?xiàng)5膽?yīng)用場(chǎng)景操作撤銷例如將操作的每組數(shù)據(jù)存入棧中,如果想要撤銷,只需要彈出棧頂元素,就可以恢復(fù)上一步操作了。最后執(zhí)行完成,根據(jù)棧的結(jié)構(gòu)開(kāi)始彈出數(shù)據(jù),一步一步再走回方法。
數(shù)據(jù)結(jié)構(gòu)-棧定義
棧(英語(yǔ):stack)又稱為堆?;蚨询B,棧作為一種數(shù)據(jù)結(jié)構(gòu),它按照先進(jìn)后出的原則存儲(chǔ)數(shù)據(jù),先進(jìn)入的數(shù)據(jù)被壓入棧底,最后的數(shù)據(jù)在棧頂,需要讀數(shù)據(jù)的時(shí)候從棧頂開(kāi)始彈出數(shù)據(jù)(最后一個(gè)數(shù)據(jù)被第一個(gè)讀出來(lái))。
由于堆疊數(shù)據(jù)結(jié)構(gòu)只允許在一端進(jìn)行操作,因而按照后進(jìn)先出(LIFO, Last In First Out)的原理運(yùn)作。棧也稱為后進(jìn)先出表
例如:將操作的每組數(shù)據(jù)存入棧中,如果想要撤銷,只需要彈出棧頂元素,就可以恢復(fù)上一步操作了。
程序調(diào)用的系統(tǒng)棧例如:A方法調(diào)用B方法得到返回值,B調(diào)用C得到返回值,A操作走到了B方法,這個(gè)時(shí)候可以將A的代碼位置存儲(chǔ)到棧中,然后走到B方法,B操作走到了C方法,這個(gè)時(shí)候可以將B的代碼位置存儲(chǔ)到棧中。最后C執(zhí)行完成,根據(jù)棧的結(jié)構(gòu)開(kāi)始彈出數(shù)據(jù),一步一步再走回A方法。
判斷括號(hào)是否有效。下文會(huì)有代碼實(shí)現(xiàn)(詳細(xì)規(guī)則描述可以參考leetcode第20題)開(kāi)括號(hào)必須用同一類型的括號(hào)閉合。
開(kāi)方括號(hào)必須按正確順序閉合。
例如:正確的:{[()]} [{()}] ({[]}) 等 。錯(cuò)誤的:[{(})] [}{()] 等。
自定義?;惖拇a實(shí)現(xiàn)棧在java.util有一個(gè)工具類,先不用,自定義實(shí)現(xiàn)一個(gè)
package com.datastructure.stack; public interface Stack{ /** * 向棧插入元素 * @param e */ public void push(E e); /** * 取出最上面的元素,并且返回 * @return */ public E pop(); /** * 獲取棧的大小 * @return */ public int getSize(); /** * 判斷棧是否為空 * @return */ public boolean isEmpty(); /** * 獲取棧最上面的元素 * @return */ public E peek(); }
package com.datastructure.stack; import com.datastructure.array.Array; /** * @program: test * @description: * @author: Mr.Yang * @create: 2019-05-02 15:27 **/ public class ArrayStackimplements Stack { Array array; public ArrayStack(int capacity){ array=new Array (capacity); } public ArrayStack(){ array=new Array (); } @Override public void push(E e) { array.addLast(e); } @Override public E pop() { return array.removeLast(); } @Override public int getSize() { return array.getSize(); } @Override public boolean isEmpty() { return array.isEmpty(); } @Override public E peek() { return array.getLast(); } /** * 獲取容量值 * @return */ public int getCapacity(){ return array.getCapacity(); } @Override public String toString(){ StringBuffer sb = new StringBuffer(); sb.append("stack: "); sb.append("["); for(int i=0;i 測(cè)試代碼
package com.datastructure.stack; /** * @program: test * @description: * @author: Mr.Yang * @create: 2019-05-02 16:11 **/ public class StackTest { public static void main(String[] args) { ArrayStackintegerArrayStack = new ArrayStack<>(); for(int i=0;i<5;i++){ integerArrayStack.push(i); System.out.println(integerArrayStack); } Integer pop = integerArrayStack.pop(); System.out.println("----移除上級(jí)元素----value is "+pop); System.out.println("-------------移除之后的棧打印------------------"); System.out.println(integerArrayStack); } } 測(cè)試結(jié)果
stack: [0] right value is stack top stack: [0, 1] right value is stack top stack: [0, 1, 2] right value is stack top stack: [0, 1, 2, 3] right value is stack top stack: [0, 1, 2, 3, 4] right value is stack top ----移除上級(jí)元素----value is 4 -------------移除之后的棧打印------------------ stack: [0, 1, 2, 3] right value is stack topleetCode第20題,花括號(hào)正確閉合思路
根據(jù)棧的數(shù)據(jù)結(jié)構(gòu)特點(diǎn),我們可以先將所有左括號(hào)‘[{(’放進(jìn)棧中,然后判斷當(dāng)前字符如果是‘)]}’這種的右括號(hào),但是棧頂?shù)睦ㄌ?hào)卻不匹配,返回false
注意控制判斷
這里使用java自帶的棧工具類來(lái)實(shí)現(xiàn)
leetcode給的測(cè)試?yán)樱?/p>
1 2 3 4 5 輸入例子 () ()[]{} (] ([)] {[]} 代碼實(shí)現(xiàn)
package com.datastructure.stack; import java.util.Stack; /** * @program: test * @description: * @author: Mr.Yang * @create: 2019-05-02 16:59 **/ public class Solution { public static void main(String[] args) { Solution solution = new Solution(); System.out.println(solution.isValid("{"name": "網(wǎng)站","num": 3,"sites": [ "Google.com", "Taobao.com", "Waibo.wang" ]}")); } public boolean isValid(String s) { Stackcharacters = new Stack<>(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == "{" || c == "[" || c == "(") { characters.push(c); } else { if(characters.isEmpty()){ return false; } Character peek = characters.pop(); switch (c) { case "}": if (!peek.equals("{")) { return false; } continue; case "]": if (!peek.equals("[")) { return false; } continue; case ")": if (!peek.equals("(")) { return false; } continue; } } } return characters.isEmpty(); } /*public boolean isValid(String s) { Stack characters = new Stack<>(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == "{" || c == "[" || c == "(") { characters.push(c); } else { if(characters.isEmpty()){ return false; } Character toChar = characters.pop(); if(c == ")" && toChar != "("){ return false; } if(c == "}" && toChar != "{"){ return false; } if(c == "]" && toChar != "["){ return false; } } } return characters.isEmpty(); }*/ } 如果想實(shí)現(xiàn)更多字符串關(guān)于括號(hào)的匹配,如JSON等等,可以根據(jù)棧的特點(diǎn)來(lái)實(shí)現(xiàn)
代碼例子GIT地址:https://git.dev.tencent.com/y...
項(xiàng)目簡(jiǎn)介:
這個(gè)項(xiàng)目是我做測(cè)試,學(xué)習(xí)的主要項(xiàng)目,目前里面包含了:一些設(shè)計(jì)模式的demo(抽象工程模式,適配器模式,外觀模式,命令模式,裝飾者模式等等)
即將學(xué)習(xí)的數(shù)據(jù)結(jié)構(gòu)demo,數(shù)組,棧,后續(xù)還會(huì)持續(xù)更新數(shù)據(jù)結(jié)構(gòu),可能會(huì)有隊(duì)列,鏈表,遞歸,紅黑樹(shù),線段樹(shù)等等一系列,如果感興趣,歡迎留言。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/74386.html
摘要:對(duì)于棧來(lái)說(shuō),這個(gè)表尾稱為棧的棧頂,相應(yīng)的表頭稱為棧底。棧和隊(duì)列的區(qū)別棧的插入和刪除操作都是在一端進(jìn)行的,而隊(duì)列的操作卻是在兩端進(jìn)行的。出棧操作出棧操作就是在棧頂取出數(shù)據(jù),棧頂指針隨之下移的操作。 基本概念 棧和隊(duì)列都是動(dòng)態(tài)的集合,在棧中,可以去掉的元素是最近插入的哪一個(gè)。棧實(shí)現(xiàn)了后進(jìn)先出。在隊(duì)列中,可以去掉的元素總是在集合中存在的時(shí)間最長(zhǎng)的那一個(gè)。隊(duì)列實(shí)現(xiàn)了先進(jìn)先出的策略。 棧的官...
摘要:介紹棧是一種后進(jìn)先出的線性表數(shù)據(jù)結(jié)構(gòu),分為棧頂和棧底兩端,僅允許在表的一端插入元素,這一端被稱為棧頂,另外一端稱之為棧底。 介紹 棧是一種后進(jìn)先出的線性表數(shù)據(jù)結(jié)構(gòu),分為棧頂和棧底兩端,僅允許在表的一端插入元素,這一端被稱為棧頂,另外一端稱之為棧底。棧,只有兩種操作,分為入棧(壓棧)和出棧(退棧);向棧中添加元素的操作叫做入棧,相反從棧中刪除元素叫做出棧。 特點(diǎn) 只能從棧頂添加元素或者...
摘要:我們都知道數(shù)組是里面比較常用的一種數(shù)據(jù)結(jié)構(gòu),棧和數(shù)組類似,定義如下棧是一種遵從后進(jìn)先出原則的有序集合。新增加和待刪除的元素都保存在棧的尾部,也稱棧頂,相反的另一端就叫棧底,在棧的這種數(shù)據(jù)結(jié)構(gòu)里面,我們新增的元素都在棧頂,舊的元素都在棧底。 由于不是計(jì)算機(jī)專業(yè)出身,對(duì)數(shù)據(jù)結(jié)構(gòu)這些了解的比較少,最近看了一些相關(guān)的書籍,這里做一些總結(jié)。本篇要說(shuō)的是棧。我們都知道數(shù)組是JavaScript里面...
摘要:則會(huì)在轉(zhuǎn)移指令前執(zhí)行。總結(jié)與之間的關(guān)系如果在中含有語(yǔ)句,那么語(yǔ)句的還有作用嗎先看一段代碼如果你對(duì)內(nèi)存布局不是很清楚,請(qǐng)看這篇文章虛擬機(jī)類加載機(jī)制和字節(jié)碼執(zhí)行引擎重點(diǎn)關(guān)注運(yùn)行時(shí)棧幀結(jié)構(gòu)局部變量表槽,操作數(shù)棧。 定論 問(wèn):finally語(yǔ)句一定會(huì)執(zhí)行嗎?答: 如果沒(méi)有執(zhí)行相應(yīng)的try語(yǔ)句則不會(huì)執(zhí)行。 在try語(yǔ)句中如果調(diào)用System.exit(0)方法則不會(huì)執(zhí)行。 問(wèn):finally...
摘要:棧的應(yīng)用前面介紹了那么多棧相關(guān)的知識(shí),最后也是介紹棧的應(yīng)用場(chǎng)景的時(shí)候了,棧的實(shí)際應(yīng)用非常廣泛,例如用來(lái)存儲(chǔ)訪問(wèn)過(guò)的任務(wù)或路徑撤銷的操作。 棧的定義 什么是棧?棧是一種遵循后進(jìn)先出原則的有序集合,新添加的或者待刪除的元素都保存在棧的同一端,稱為棧頂,另一端稱為棧底,在棧里,新元素靠近棧頂,舊元素靠近棧底,用個(gè)圖來(lái)看大概這樣式的:showImg(https://segmentfault.c...
摘要:調(diào)用棧的運(yùn)行機(jī)制機(jī)制程序運(yùn)行到一個(gè)函數(shù),它就會(huì)將其添加到調(diào)用棧中,當(dāng)從這個(gè)函數(shù)返回的時(shí)候,就會(huì)將這個(gè)函數(shù)從調(diào)用棧中刪掉。在調(diào)用棧中每個(gè)調(diào)用偵都對(duì)應(yīng)一個(gè)函數(shù),最上方的調(diào)用幀稱為當(dāng)前幀,調(diào)用棧是由所有的調(diào)用偵形成的。 showImg(https://segmentfault.com/img/remote/1460000019244497?w=900&h=600); 調(diào)用棧的英文名叫做Cal...
閱讀 3431·2021-11-10 11:36
閱讀 3323·2021-10-08 10:21
閱讀 2936·2021-09-29 09:35
閱讀 2501·2021-09-22 16:06
閱讀 4096·2021-09-09 09:33
閱讀 1387·2019-08-30 15:44
閱讀 3231·2019-08-30 10:59
閱讀 3055·2019-08-29 15:32