最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)鏈棧的示例代碼

 更新時(shí)間:2022年11月15日 08:50:30   作者:m0_46897923  
這篇文章主要為大家詳細(xì)介紹了如何使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)來實(shí)現(xiàn)棧,也就是鏈棧的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下

前言

線性表和棧都是我們常用的數(shù)據(jù)結(jié)構(gòu),??梢钥闯梢环N特殊狀態(tài)的線性表,棧的實(shí)現(xiàn),一般都是使用線性表來實(shí)現(xiàn),線性表分為順序表和鏈表,使用線性表中的順序表來實(shí)現(xiàn)棧時(shí)這種棧被稱為順序棧,相應(yīng)的使用線性表中的鏈表來實(shí)現(xiàn)棧時(shí)這種棧被稱為鏈棧,但是需要說明的是,雖然棧是一種特殊的線性表,但是棧和線性表并不是一種數(shù)據(jù)結(jié)構(gòu)。這篇文章總結(jié)如何使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)來實(shí)現(xiàn)棧,也就是鏈棧的實(shí)現(xiàn)。如果想要了解另一種棧(順序棧)的實(shí)現(xiàn)請看這里:順序棧的實(shí)現(xiàn)

一、實(shí)現(xiàn)過程

這部分總結(jié)鏈棧的實(shí)現(xiàn)過程,以及對應(yīng)方法實(shí)現(xiàn)思路,這里提供一個(gè)棧的頂層接口IStack,用以聲明棧中所應(yīng)實(shí)現(xiàn)的方法,提供該接口不僅可供鏈棧使用,順序棧也是可以使用的。下面鏈棧的實(shí)現(xiàn)通過實(shí)現(xiàn)ISstack接口來完成,詳細(xì)步驟如下。

1.提供棧接口:IStack

該接口定義了棧必須實(shí)現(xiàn)的接口,有如下方法:

/**
 * 該接口是:棧的頂層接口
 * 他的實(shí)現(xiàn)類會(huì)有:順序棧、鏈棧
 *
 * 棧:先入后出
 */
public interface IStack {
    void clear();//清空方法
    boolean isEmpty();//判空方法
    int length();//棧深度方法
    Object peek();//取棧頂元素并返回值,若棧為空,返回null
    void push(Object object) throws Exception;//入棧操作,元素進(jìn)入棧頂
    Object pop();//將棧頂元素出站
}

2.提供結(jié)點(diǎn)類:Node

鏈棧的實(shí)現(xiàn)使用單鏈表來實(shí)現(xiàn),因此我們需要提供一個(gè)結(jié)點(diǎn)的信息類,該結(jié)點(diǎn)是鏈表的存儲(chǔ)單元,他包含有兩個(gè)屬性,一個(gè)是數(shù)據(jù)域用以存儲(chǔ)數(shù)據(jù),一個(gè)是指針域用以指向下一個(gè)結(jié)點(diǎn),這兩個(gè)屬性這里都聲明成了public,也可以聲明成private,這樣就需要使用get、set方法來操作這些屬性了,這里為了方便使用public來聲明這兩個(gè)屬性。

public class Node {
    public Object object;
    public Node next;

    public Node(){
    }
    public Node(Object object){
        this.object = object;
    }
    public Node(Node next){
        this.next = next;
    }
    public Node(Object object,Node next){
        this.object = object;
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" +
                "object=" + object +
                ", next=" + next +
                '}';
    }
}

3.提供鏈棧的實(shí)現(xiàn)類:LinkedStack

使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)實(shí)現(xiàn)的棧被稱為鏈棧,這里使用單鏈表的數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn),該單鏈表的實(shí)現(xiàn)可以使用帶頭結(jié)點(diǎn)和不帶頭結(jié)點(diǎn)兩種方式。兩種實(shí)現(xiàn)沒有太大區(qū)別,這里使用不帶頭結(jié)點(diǎn)的方式來實(shí)現(xiàn)。不帶頭結(jié)點(diǎn)那我們需要提供一個(gè)首結(jié)點(diǎn),首結(jié)點(diǎn)需要在棧創(chuàng)建時(shí)被初始化,代碼如下:

/**
 *
 * @author pcc
 * @version 1.0.0
 * @className LinkedStack:該棧類,使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)實(shí)現(xiàn),是鏈棧,這里使用單鏈表的方式實(shí)現(xiàn)
 * @date 2021-04-20 16:32
 *
 * 棧的特點(diǎn)是先進(jìn)后出:
 * 因此我們可以使用頭插法,每次在頭部插入,出棧時(shí)只需獲取鏈表的頭結(jié)點(diǎn)即可。
 *
 * 鏈棧與順序棧的區(qū)別:
 * 順序棧底層是數(shù)組,因此必須初始化一個(gè)數(shù)組的容量,也就是棧的容量,鏈棧則無需此操作
 * 對比鏈棧和順序棧的實(shí)現(xiàn),可以發(fā)現(xiàn)入棧和出戰(zhàn)方法的時(shí)間復(fù)雜度都是O(1),效率上沒有區(qū)別,但是順序棧占用的空間會(huì)相對更多
 * 一些,順序棧是通過指針指向假設(shè)的棧頂,其他元素其實(shí)依然存在,但鏈棧的棧頂之前的元素會(huì)被垃圾回收,因此鏈棧的實(shí)現(xiàn)綜合時(shí)間和
 * 空間來看,更優(yōu)秀一些。
 */
public class LinkedStack implements IStack {
    //這是首結(jié)點(diǎn)
    Node node;

    public LinkedStack(){
        node = new Node();
    }
}

4.提供清空(clear)、判空(isEmpty)、棧深度(length)等方法

這些方法的實(shí)現(xiàn)都比較簡單,都一起寫了,鏈表的起始就是首結(jié)點(diǎn),因此我們只需要將首結(jié)點(diǎn)的數(shù)據(jù)域與指針域置空即可實(shí)現(xiàn)鏈棧的清空。判空也只需要判斷首結(jié)點(diǎn)的數(shù)據(jù)域是否有值即可。棧深度則需要遍歷鏈表的長度了(也可以設(shè)置一個(gè)整型,每次入棧操作時(shí)整型加1,這里通過遍歷實(shí)現(xiàn))。

下面是三個(gè)方法的實(shí)現(xiàn):

    @Override
    public void clear() {
        node.next = null;
        node.object = null;
    }

    @Override
    public boolean isEmpty() {
        return node.object==null?true:false;
    }

    @Override
    public int length() {
        if(node.object==null)
            return 0;
        int j= 1;
        Node nodeNew = node;
        while(nodeNew.next!=null){
            j++;
            nodeNew = nodeNew.next;
        }
        return j;
    }

5.提供入棧的方法:push(Object object)

入棧方法當(dāng)然就是將數(shù)據(jù)元素放入棧頂?shù)牟僮髁?。首先我們?yīng)該知道對于鏈表每次獲取鏈表首結(jié)點(diǎn)的時(shí)間復(fù)雜度是O(1),獲取尾結(jié)點(diǎn)的時(shí)間復(fù)雜度是O(n),因此很明顯我們使用鏈表作為棧的數(shù)據(jù)結(jié)構(gòu)時(shí),應(yīng)該使用頭插法來將數(shù)據(jù)存入鏈棧,這樣我們每次插入的棧頂元素都在鏈表的開始位置,獲取該結(jié)點(diǎn)的時(shí)間復(fù)雜度是O(1)。所以我們使用頭插法實(shí)現(xiàn)數(shù)據(jù)的存儲(chǔ),代碼如下:

    @Override
    public void push(Object object) throws Exception {
        if(node.object==null){
            node.object = object;
            return;
        }
        //頭插法
        node = new Node(object,node);
    }

6.提供獲取棧頂元素方法:peek()

該方法只是獲取棧頂元素的信息,并不會(huì)將該元素出棧,因?yàn)闂m斣鼐褪擎湵淼氖捉Y(jié)點(diǎn),因此我們只需要返回首結(jié)點(diǎn)的數(shù)據(jù)域即可,代碼實(shí)現(xiàn)如下:

    @Override
    public Object peek() {
        return node.object;
    }

7.提供出棧方法:pop()

棧是一種先入后出的數(shù)據(jù)結(jié)構(gòu),每次出棧的只能是最后進(jìn)入的數(shù)據(jù)元素,因此我們每次只需要將鏈棧的首結(jié)點(diǎn)出棧即可,代碼實(shí)現(xiàn)如下:

    @Override
    public Object pop() {
        if(node.object==null)
            return null;
        Node tem = node;
        node = node.next==null?new Node():node.next;
        return tem.object;
    }

8.提供鏈棧的完整實(shí)現(xiàn)代碼

/**
 *
 * @author pcc
 * @version 1.0.0
 * @className LinkedStack:該棧類,使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)實(shí)現(xiàn),是鏈棧,這里使用單鏈表的方式實(shí)現(xiàn)
 * @date 2021-04-20 16:32
 *
 * 棧的特點(diǎn)是先進(jìn)后出:
 * 因此我們可以使用頭插法,每次在頭部插入,出棧時(shí)只需獲取鏈表的頭結(jié)點(diǎn)即可。
 *
 * 鏈棧與順序棧的區(qū)別:
 * 順序棧底層是數(shù)組,因此必須初始化一個(gè)數(shù)組的容量,也就是棧的容量,鏈棧則無需此操作
 * 對比鏈棧和順序棧的實(shí)現(xiàn),可以發(fā)現(xiàn)入棧和出戰(zhàn)方法的時(shí)間復(fù)雜度都是O(1),效率上沒有區(qū)別,但是順序棧占用的空間會(huì)相對更多
 * 一些,順序棧是通過指針指向假設(shè)的棧頂,其他元素其實(shí)依然存在,但鏈棧的棧頂之前的元素會(huì)被垃圾回收,因此鏈棧的實(shí)現(xiàn)綜合時(shí)間和
 * 空間來看,更優(yōu)秀一些。
 */
public class LinkedStack implements IStack {
    //這是首結(jié)點(diǎn)
    Node node;

    public LinkedStack(){
        node = new Node();
    }

    @Override
    public void clear() {
        node.next = null;
        node.object = null;
    }

    @Override
    public boolean isEmpty() {
        return node.object==null?true:false;
    }

    @Override
    public int length() {
        if(node.object==null)
            return 0;
        int j= 1;
        Node nodeNew = node;
        while(nodeNew.next!=null){
            j++;
            nodeNew = nodeNew.next;
        }
        return j;
    }

    @Override
    public Object peek() {
        return node.object;
    }

    @Override
    public void push(Object object) throws Exception {
        if(node.object==null){
            node.object = object;
            return;
        }
        //頭插法
        node = new Node(object,node);
    }

    @Override
    public Object pop() {
        if(node.object==null)
            return null;
        Node tem = node;
        node = node.next==null?new Node():node.next;
        return tem.object;
    }
}

二、測試鏈棧的相應(yīng)方法

第一部分已經(jīng)詳細(xì)描述了鏈棧的實(shí)現(xiàn)過程,下面就來測試下這些方法是否可以正常使用吧。

1.測試入棧和出棧

創(chuàng)建一個(gè)測試類,然后往棧中插入五個(gè)數(shù)據(jù)元素,并依次出棧,若是出棧順序和入棧順序相反則說明是正確的了,測試結(jié)果如下圖:

可以看見輸出和輸入順序是相反的,結(jié)果滿足先入后出的預(yù)期。說明入棧與出棧的操作沒有問題。

2.驗(yàn)證獲取棧頂元素方法peek、棧深度方法length、清空方法clear

還是往棧里面放入原先的五個(gè)元素,然后棧頂元素應(yīng)該是“李四5”,長度應(yīng)該是5,第二次長度應(yīng)該是0,如果輸出內(nèi)容是這些說明棧的實(shí)現(xiàn)就沒有問題了,結(jié)果見下圖:

從輸出結(jié)果可以看到,這些方法實(shí)現(xiàn)并沒有問題,到這里棧常用的所有方法就已經(jīng)都實(shí)現(xiàn)了,方法的實(shí)現(xiàn)都很簡單,并沒有有難度的地方。

三、總結(jié)

鏈棧即使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)實(shí)現(xiàn)的棧,其實(shí)這里的鏈棧就是一個(gè)特殊的單鏈表,一種限制了只能在首結(jié)點(diǎn)插入和刪除的單鏈表。這也是鏈表的本質(zhì),無論是在何種語言中棧的實(shí)現(xiàn)要么是使用順序表要么是使用鏈表。無論使用哪種方法實(shí)現(xiàn)其實(shí)都很簡單。

1.順序棧與鏈棧的區(qū)別

順序棧與鏈棧作為兩種不同的棧的實(shí)現(xiàn),他們肯定是有區(qū)別的,我們首先對比下入棧的操作,順序棧的入棧操作是直接根據(jù)頭指針將數(shù)據(jù)加入到數(shù)組指定的下標(biāo)位置,鏈棧的入棧則是直接在首結(jié)點(diǎn)插入,他們的時(shí)間復(fù)雜度都是O(1),那么再對比下出棧的操作,順序棧是通過頭指針直接拿到下標(biāo)為頭指針的數(shù)組元素,鏈棧則是直接將鏈表的頭部刪除返回,他們的時(shí)間復(fù)雜度也都是O(1),因此在入棧和出棧的操作上他們的性能并沒有什么區(qū)別,其他的區(qū)別還是要看不同的實(shí)現(xiàn),若是實(shí)現(xiàn)的順序棧每次出棧后不刪除棧頂以后的元素,則順序棧會(huì)占用更多的空間,因?yàn)殒湕C看纬鰲:笏臄?shù)據(jù)元素與GC ROOTS就失去了連接,下次觸發(fā)GC時(shí)就會(huì)回收相應(yīng)內(nèi)存。這種情況順序棧會(huì)占用更多的空間,鏈棧則更少,但是若是每次出棧時(shí)將順序棧頭指針以后的數(shù)據(jù)元素刪除,就不會(huì)有這種區(qū)別了,所以綜合來說順序棧與鏈棧在入棧和出棧的操作上性能沒有區(qū)別,但是其他場景的性能消耗,比如空間復(fù)雜度上則需要看順序棧與鏈棧的具體實(shí)現(xiàn)來定。

到此這篇關(guān)于Java實(shí)現(xiàn)鏈棧的示例代碼的文章就介紹到這了,更多相關(guān)Java鏈棧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA中取整數(shù)的4種方法總結(jié)

    JAVA中取整數(shù)的4種方法總結(jié)

    這篇文章主要給大家介紹了關(guān)于JAVA中取整數(shù)的4種方法,在java的Math類中,提供了許許多多的和數(shù)學(xué)計(jì)算有關(guān)的方法,其中也包括取整的,需要的朋友可以參考下
    2023-07-07
  • 一文詳解Java屬性為什么不能是is開頭的boolean

    一文詳解Java屬性為什么不能是is開頭的boolean

    在Java實(shí)體類定義中,boolean類型的屬性命名常引發(fā)爭議,阿里巴巴Java開發(fā)手冊建議避免使用is作為布爾類型屬性的前綴,原因在于當(dāng)實(shí)體類被序列化或反序列化時(shí),基于JavaBean規(guī)范的框架可能會(huì)移除或忽略is,導(dǎo)致不一致的字段名,文中介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • Java使用自定義注解實(shí)現(xiàn)為事件源綁定事件監(jiān)聽器操作示例

    Java使用自定義注解實(shí)現(xiàn)為事件源綁定事件監(jiān)聽器操作示例

    這篇文章主要介紹了Java使用自定義注解實(shí)現(xiàn)為事件源綁定事件監(jiān)聽器操作,結(jié)合實(shí)例形式分析了java自定義注解、注解處理、事件監(jiān)聽與響應(yīng)等相關(guān)操作技巧,需要的朋友可以參考下
    2019-10-10
  • IDEA中設(shè)置Run Dashboard方式

    IDEA中設(shè)置Run Dashboard方式

    這篇文章主要介紹了IDEA中設(shè)置Run Dashboard方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot實(shí)現(xiàn)向量數(shù)據(jù)庫優(yōu)化檢索的方案及示例

    SpringBoot實(shí)現(xiàn)向量數(shù)據(jù)庫優(yōu)化檢索的方案及示例

    在Spring?Boot中實(shí)現(xiàn)RAG(Retrieval-Augmented?Generation)的增強(qiáng),可以從檢索優(yōu)化、生成優(yōu)化和系統(tǒng)架構(gòu)三個(gè)維度進(jìn)行改進(jìn),本文給大家介紹了具體實(shí)現(xiàn)方案及示例,需要的朋友可以參考下
    2025-02-02
  • spring?mybatis環(huán)境常量與枚舉轉(zhuǎn)換示例詳解

    spring?mybatis環(huán)境常量與枚舉轉(zhuǎn)換示例詳解

    這篇文章主要為大家介紹了spring?mybatis環(huán)境常量與枚舉轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • ChatGPT-4.0未來已來 你來不來

    ChatGPT-4.0未來已來 你來不來

    最近聽說了一個(gè)非?;鸬募夹g(shù)ChatGPT4.0,今天這篇文章就給大家介紹一下ChatGPT究竟是什么東東,不得不說ChatGPT是真的強(qiáng),下面就讓我們一起了解究竟什么是ChatGPT吧
    2023-03-03
  • SpringBoot3集成和使用Jasypt的代碼詳解

    SpringBoot3集成和使用Jasypt的代碼詳解

    隨著信息安全的日益受到重視,加密敏感數(shù)據(jù)在應(yīng)用程序中變得越來越重要,Jasypt作為一個(gè)簡化Java應(yīng)用程序中數(shù)據(jù)加密的工具,為開發(fā)者提供了一種便捷而靈活的加密解決方案,本文將深入解析Jasypt的工作原理,需要的朋友可以參考下
    2024-01-01
  • IO 使用說明介紹

    IO 使用說明介紹

    本篇文章小編為大家介紹,IO 使用說明介紹。需要的朋友參考下
    2013-04-04
  • Java性能的十一個(gè)用法分享

    Java性能的十一個(gè)用法分享

    這篇文章主要介紹了Java性能的十一個(gè)用法,需要的朋友可以參考下
    2014-10-10

最新評論

岱山县| 德惠市| 柳林县| 乐昌市| 巫山县| 武定县| 梧州市| 乐平市| 鲁甸县| 大荔县| 庐江县| 呼图壁县| 丁青县| 宁阳县| 普兰县| 南雄市| 南皮县| 松原市| 太湖县| 木兰县| 茌平县| 辰溪县| 温泉县| 阿拉善右旗| 龙州县| 剑河县| 本溪市| 镇坪县| 灵武市| 区。| 阳山县| 长宁县| 翁源县| 客服| 和硕县| 雷山县| 泗洪县| 青川县| 栖霞市| 睢宁县| 蒙山县|