App下載

動圖演示:手擼堆棧的兩種實現(xiàn)方法!

猿友 2020-09-23 11:31:53 瀏覽數 (2937)
反饋

文章來源于公眾號:Java中文社群 作者:磊哥

隨著軟件開發(fā)行業(yè)競爭的日益激烈,面試的難度也在逐漸增加,因為企業(yè)要從眾多的面試人中選出最優(yōu)秀的人,只能提高面試的難度,而算法和數據結構比較燒腦的硬核技能之一,自然也就成了面試的首選科目。并且隨著時間的推移,算法和數據結構出現(xiàn)的頻率和占比也會不斷增加,因此為了順應時代發(fā)展的潮流,我們也要做一些調整,所以在后面的一些文章中,我會陸續(xù)更新一些關于算法和數據結構的文章,希望大家能夠喜歡。

PS:當然隨著智能系統(tǒng)的普及(如今日頭條和抖音),算法和數據結構在企業(yè)中應用也越來越多,因此學習算法和數據結構也是迫在眉睫的事了。

棧定義

棧(Stack)又叫堆棧(簡稱棧),它是在同一端進行插入和刪除數據的線性表。

棧是最基礎也是最常見的數據結構之一,它的數據結構和操作流程如下圖所示:

棧的數據結構和操作流程

其中,允許進行插入和刪除的一端叫作棧頂(Top),另一端叫作棧底(Bottom),棧底固定,棧頂浮動。

當棧中的元素為零時,該棧叫作空棧。添加數據時一般叫作入?;蜻M棧(Push),刪除數據叫作出棧或退棧(Pop)。棧是后進先出(Last In First Out,LIFO)的線性表

棧是后進先出的線性表

物理結構 & 邏輯結構

在手擼算法之前,我們先來認識一下數據結構中的兩個重要概念:物理結構和邏輯結構。

當談到“物理”和“邏輯”一詞時,我們可以會想到數據庫中的邏輯刪除和物理刪除。

所謂的物理刪除是指通過刪除命令真實的將數據從物理結構中刪除的過程;而邏輯刪除是指通過修改命令將數據更改為“已刪除”的狀態(tài),并非真實的刪除數據。

這里的邏輯結構和物理結構和上面的概念類似,所謂的物理結構是指可以將數據存儲在物理空間中,比如數組和鏈表都屬于物理數據結構;而邏輯結構則是用于描述數據間的邏輯關系的,比如本文要講的棧就屬于邏輯結構。

太難了,我不聽

可能有些人看到這里就蒙了,沒關系,我這里舉一個例子你就明白了。

如果用人來表示物理結構和邏輯結構的話,那么真實存在的有血有肉的人就屬于物理結構,而人的思想和信念就屬于邏輯結構了

物理結構和邏輯結構

自定義棧I:數組實現(xiàn)

通過上面的內容,我們知道了棧屬于邏輯結構,因此它的實現(xiàn)方式就可以有很多種了,比如數組的實現(xiàn)方式或者是鏈表的實現(xiàn)方式。那么我們就先用數組實現(xiàn)一下,棧的主要方法有:

棧的主要方法

① 定義結構

那么我們先來定義它的結構:

public class MyStack {
    private Object[] value = null; // 棧存儲容器
    private int top = -1; // 棧頂(的指針)
    private int maxSize = 0; // 棧容量


    // 構造函數(初始化默認容量)
    MyStack() {
        this.maxSize = 10;
    }


    // 有參構造函數
    MyStack(int initSize) throws Exception {
        if (initSize  Hello


從上述代碼可以看出,我們添加棧的順序是 `Hello`、`Java` 而輸出的順序是 `Java`、 `Hello` 符合棧的定義(后進先出)。


## 自定義棧II:鏈表實現(xiàn)


除了數組之外,我們可以還可使用鏈表來實現(xiàn)棧結構,它的實現(xiàn)稍微復雜一些,我們先來看鏈表本身的數據結構:


![鏈表的數據結構](https://atts.w3cschool.cn/attachments/image/20200923/1600831705876009.png "鏈表的數據結構")


使用鏈表實現(xiàn)棧的流程如下:


![鏈表實現(xiàn)棧的流程](https://atts.w3cschool.cn/attachments/image/20200923/1600831725907957.gif "鏈表實現(xiàn)棧的流程")


也就是說,入棧時我們將數據存儲在鏈表的頭部,出棧時我們從頭部進行移除,并將棧頂指針指向原頭部元素的下一個元素,實現(xiàn)代碼如下。


我們先來定義一個鏈表節(jié)點:

public class Node { Object value; // 每個節(jié)點的數據 Node next; // 下一個節(jié)點

public Node(Object value) { this(value, null); }

/**

  • 創(chuàng)建新節(jié)點
  • @param value 當前節(jié)點數據
  • @param next 指向下一個節(jié)點(頭插法) */ public Node(Object value, Node next) { this.value = value; this.next = next; } }

接下來我們使用鏈表來實現(xiàn)一個完整的棧:


public class StackByLinked {


    private Node top = null; // 棧頂數據
    private int maxSize = 0; // 棧最大容量
    private int leng = 0; // 棧實際容量


    public StackByLinked(int initSize) throws Exception {
        if (initSize = maxSize;
    }


    /**
     * 是否為空
     * @return
     */
    public boolean isEmpty() {
        return leng  Java
>
> Hello


## 總結


本文我們使用了數組和鏈表等物理結構來實現(xiàn)了棧,當然我們也可以使用其他容器來實現(xiàn),比如 [Java](http://www.o2fo.com/java/) 中的 `List`,我們只需要保證在操作棧時是后進先出的執(zhí)行順序,并且至少包含 3 個重要方法:入棧、出棧和查詢棧頂元素就可以了。


## 最后


**算法和數據結構的學習是 3 分學 7 分練**,只看不練是沒辦法學好算法的,而且**學習算法和數據結構是一個循序漸進的過程,短時間內不會有明顯的收效**。因為這些算法經過了幾百年的發(fā)展和積累才得以流傳下來的,所以想要“玩得轉”還需要一點耐心。


這里給你講一個學習算法的“秘訣”:**看不懂的知識要反復看,如果反復看還是看不懂,那么別著急,休息一下再繼續(xù)看!**相信我,對于學習算法這件事,所有人的過程都是一樣的。


以上就是`W3Cschool編程獅`關于**動圖演示:手擼堆棧的兩種實現(xiàn)方法!**的相關介紹了,希望對大家有所幫助。

0 人點贊