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

Java棧和基礎(chǔ)隊(duì)列的實(shí)現(xiàn)詳解

 更新時(shí)間:2022年02月14日 14:54:58   作者:Word碼鴨  
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)中的棧與隊(duì)列,在Java的時(shí)候,對(duì)于棧與隊(duì)列的應(yīng)用需要熟練的掌握,這樣才能夠確保Java學(xué)習(xí)時(shí)候能夠有扎實(shí)的基礎(chǔ)能力。本文小編就來(lái)詳細(xì)說(shuō)說(shuō)Java中的棧與隊(duì)列,需要的朋友可以參考一下

棧和隊(duì)列:都是線性表,都是基于List基礎(chǔ)上的實(shí)現(xiàn)

線性表:數(shù)組,鏈表,字符串,棧,隊(duì)列

元素按照一條“直線”排列,線性表這個(gè)結(jié)構(gòu)中,一次添加單個(gè)元素

棧(stack)

一種特殊的線性表,其只允許在固定的一端進(jìn)行插入和刪除元素操作。進(jìn)行數(shù)據(jù)插入和刪除操作的一端稱為棧頂,另一端稱為棧底。棧中的數(shù)據(jù)元素遵守后進(jìn)先出LIFO(Last In First Out)的原則。

20191212190125865.gif (1920×1080)

20191212204731172.gif (1920×1080)

棧支持的三個(gè)核心操作:

  • 入棧push
  • 出棧pop
  • 返回棧頂元素peek  

棧的常見(jiàn)實(shí)際應(yīng)用:

  • 無(wú)處不在的撤銷(xiāo)操作undo,一般任意的編輯器都使用 ctrl + z 操作,其實(shí)本質(zhì)就是每次操作一次 ctrl + z 就是一次棧的pop
  • 瀏覽器的前進(jìn)后退,瀏覽器維護(hù)了一個(gè)棧結(jié)構(gòu)A->B->C,此時(shí)頁(yè)面停留在C,想要回到頁(yè)面B,點(diǎn)擊后退鍵頭就相當(dāng)于將C出棧,此時(shí)的棧頂就是B
  • 在開(kāi)發(fā)程序中的“調(diào)用棧”操作系統(tǒng)棧底層就是棧的實(shí)現(xiàn)

棧的實(shí)現(xiàn)

棧是一種線性表,所以實(shí)現(xiàn)它即可使用數(shù)組,也可以使用鏈表

  • 基于數(shù)組實(shí)現(xiàn)的棧—順序棧(棧頂實(shí)際就是數(shù)組尾部,在數(shù)組尾部添加和刪除)
  • 基于鏈表實(shí)現(xiàn)的棧—鏈?zhǔn)綏#ㄦ湵淼念^插和尾插)

在數(shù)組尾部進(jìn)行刪除和插入的時(shí)間復(fù)雜度為O(1),所以用數(shù)組實(shí)現(xiàn)棧是我們的首選

實(shí)現(xiàn)代碼:

//基于數(shù)組實(shí)現(xiàn)的棧
public class MyStack<E> {
    private int size;//數(shù)組長(zhǎng)度
    //實(shí)際存儲(chǔ)數(shù)據(jù)的動(dòng)態(tài)數(shù)組
    private List<E> data = new ArrayList<>();
    
    //入棧,默認(rèn)尾插
    public void push(E val){
        data.add(val);
        size ++;
    }
    
    //彈出棧頂元素,返回棧頂?shù)闹?
    public E pop(){
        if(isEmpty()){
            //棧為空
            throw new NoSuchElementException("stack is empty!cannot pop!");
        }
        //刪元素
       E val =  data.remove(size-1);
        size--;
        return val;
        //上面三句等同于return data.remove(size-1);
    }
    
    //返回棧頂元素,但不出棧
    public E peek(){
        if(isEmpty()){
            throw new NoSuchElementException("stack is empty!cannot peek");
        }
        return data.get(size-1);
    }
    
    // 判斷當(dāng)前棧是否為空
    public boolean isEmpty() {
        return size == 0;
    }
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(data.get(i));
            if (i != size - 1) {
                // 此時(shí)還沒(méi)到棧頂,還沒(méi)到數(shù)組末尾
                sb.append(", ");
            }
        }
        sb.append("] top");
        return sb.toString();
    }
}
 
//--------------------------
//測(cè)試類(lèi)·
public class StackTest {
    public static void main(String[] args) {
        MyStack<Integer> myStack = new MyStack<>();
        myStack.push(1);
        myStack.push(3);
        myStack.push(5);
        System.out.println(myStack);
        System.out.println(myStack.pop());//刪除棧頂
        System.out.println(myStack.peek());//輸出棧頂,此時(shí)棧頂為3
        System.out.println(myStack.isEmpty());
    }
}

//輸出結(jié)果:
[1, 3, 5] top
5
3
false

隊(duì)列

只允許在一端進(jìn)行插入數(shù)據(jù)操作,在另一端進(jìn)行刪除數(shù)據(jù)操作的特殊線性表,隊(duì)列遵循先進(jìn)先出FIFO(First In First Out)的原則 :進(jìn)行插入操作的一端稱為隊(duì)尾(Tail/Rear) 出隊(duì)列:進(jìn)行刪除操作的一端稱為隊(duì)頭

其實(shí)隊(duì)列的定義很簡(jiǎn)單,就相當(dāng)于我們現(xiàn)實(shí)生活的排隊(duì)購(gòu)物,先排隊(duì)的人先結(jié)賬,也就先離開(kāi)

隊(duì)列的子類(lèi)比棧要復(fù)雜一些,它有:

  • 基礎(chǔ)隊(duì)列—FIFO
  • 基于優(yōu)先級(jí)的隊(duì)列—按照優(yōu)先級(jí)大小出隊(duì)
  • 循環(huán)隊(duì)列—基于數(shù)組實(shí)現(xiàn)的
  • 雙端隊(duì)列

無(wú)論是哪種隊(duì)列,都必須支持三個(gè)核心操作:

  • 入隊(duì)—offer
  • 出隊(duì)—poll
  • 返回隊(duì)首元素—peek  

基礎(chǔ)隊(duì)列的實(shí)現(xiàn) 

  • 基于數(shù)組實(shí)現(xiàn)的隊(duì)列—順序隊(duì)列
  • 基于鏈表實(shí)現(xiàn)的隊(duì)列—鏈?zhǔn)疥?duì)列

由于隊(duì)列是從隊(duì)尾插入,隊(duì)首出隊(duì),而在數(shù)組頭部刪除的時(shí)間復(fù)雜度為O(n),此時(shí)我們用鏈表會(huì)更好一些。而且無(wú)論實(shí)現(xiàn)哪種隊(duì)列都需要覆寫(xiě)三個(gè)基本操作,因此我們將隊(duì)列設(shè)計(jì)為接口

實(shí)現(xiàn)代碼:

public interface Queue<E> {
    // 入隊(duì)
    void offer(E val);
    // 出隊(duì)
    E poll();
    // 返回隊(duì)首元素
    E peek();
    // 判斷隊(duì)列是否為空
    boolean isEmpty();
}
 
 //基于鏈表實(shí)現(xiàn)的基礎(chǔ)隊(duì)列
public class MyQueue<E> implements Queue<E> {
    // 鏈表的每個(gè)節(jié)點(diǎn)
    // ------------------------------
    //內(nèi)部類(lèi)
    private class Node {
        E val;
        Node next;
        public Node(E val) {
            this.val = val;
        }
    }
    // ------------------------------
    // 當(dāng)前隊(duì)列中的元素個(gè)數(shù)
    private int size;
    // 隊(duì)首
    private Node head;
    // 隊(duì)尾
    private Node tail;
    @Override
    public void offer(E val) {
        Node node = new Node(val);
        if (head == null) {
            // 此時(shí)鏈表為空
            head = tail = node;
        }else {
            tail.next = node;
            tail = node;
        }
        size ++;
    }
 
    @Override
    public E poll() {
        if (isEmpty()) {
            throw new NoSuchElementException("queue is empty!cannot poll!");
        }
        E val = head.val;
        Node node = head;
        head = head.next;
        // 將原來(lái)頭節(jié)點(diǎn)脫鉤
        node.next = null;
        size --;
        return val;
    }
 
    @Override
    public E peek() {
        if (isEmpty()) {
            throw new NoSuchElementException("queue is empty!cannot peek!");
        }
        return head.val;
    }
 
    @Override
    public boolean isEmpty() {
        return size == 0;
    }
 
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("front [");
        // 鏈表的遍歷
        for (Node x = head;x != null;x = x.next) {
            sb.append(x.val);
            if (x.next != null) {
                // 還沒(méi)走到鏈表尾部
                sb.append(", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }
}
 
//測(cè)試類(lèi)
public class QueueTest {
    public static void main(String[] args) {
        Queue<Integer> queue = new MyQueue<>();
        queue.offer(1);
        queue.offer(3);
        queue.offer(5);
        System.out.println(queue);
    }
}

作為初學(xué)者,我們不能小瞧任何簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)與算法,基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)往往作為高階數(shù)據(jù)結(jié)構(gòu)的一部分來(lái)應(yīng)用,萬(wàn)丈高樓平地起,平時(shí)要多加練習(xí),我們一起加油!

到此這篇關(guān)于Java棧和基礎(chǔ)隊(duì)列的實(shí)現(xiàn)詳解的文章就介紹到這了,更多相關(guān)Java 棧和基礎(chǔ)隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 重寫(xiě)時(shí)應(yīng)當(dāng)遵守的 11 條規(guī)則

    Java 重寫(xiě)時(shí)應(yīng)當(dāng)遵守的 11 條規(guī)則

    這篇文章主要介紹了Java 重寫(xiě)時(shí)應(yīng)當(dāng)遵守的 11 條規(guī)則,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • spring?項(xiàng)目實(shí)現(xiàn)限流方法示例

    spring?項(xiàng)目實(shí)現(xiàn)限流方法示例

    這篇文章主要為大家介紹了spring項(xiàng)目實(shí)現(xiàn)限流的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • resty的緩存技術(shù)設(shè)計(jì)及使用

    resty的緩存技術(shù)設(shè)計(jì)及使用

    這篇文章主要為大家介紹了resty緩存技術(shù)的設(shè)計(jì)及使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • SpringBoot + WebSocket 實(shí)現(xiàn)答題對(duì)戰(zhàn)匹配機(jī)制案例詳解

    SpringBoot + WebSocket 實(shí)現(xiàn)答題對(duì)戰(zhàn)匹配機(jī)制案例詳解

    這篇文章主要介紹了SpringBoot + WebSocket 實(shí)現(xiàn)答題對(duì)戰(zhàn)匹配機(jī)制,分別為每個(gè)用戶擬定四種在線狀態(tài),通過(guò)流程圖給大家展示,需要的朋友可以參考下
    2021-05-05
  • Java調(diào)用阿里身份證實(shí)現(xiàn)驗(yàn)證接口

    Java調(diào)用阿里身份證實(shí)現(xiàn)驗(yàn)證接口

    這篇文章主要為大家詳細(xì)介紹了Java如何調(diào)用阿里身份證實(shí)現(xiàn)驗(yàn)證接口,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下
    2023-06-06
  • 一篇文章教你如何在SpringCloud項(xiàng)目中使用OpenFeign

    一篇文章教你如何在SpringCloud項(xiàng)目中使用OpenFeign

    這篇文章主要介紹了SpringCloud 使用Open feign 優(yōu)化詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-08-08
  • Java數(shù)組的動(dòng)態(tài)初始化和常見(jiàn)問(wèn)題解析

    Java數(shù)組的動(dòng)態(tài)初始化和常見(jiàn)問(wèn)題解析

    本文介紹了數(shù)組動(dòng)態(tài)初始化的概念,即在初始化時(shí)僅指定數(shù)組長(zhǎng)度,系統(tǒng)會(huì)為數(shù)組分配初始值,而靜態(tài)初始化則手動(dòng)指定數(shù)組元素,系統(tǒng)根據(jù)元素個(gè)數(shù)計(jì)算數(shù)組長(zhǎng)度,這兩種初始化方式應(yīng)用場(chǎng)景不同,另外,還講述了數(shù)組默認(rèn)初始化值的規(guī)律及數(shù)組常見(jiàn)問(wèn)題,如越界問(wèn)題等
    2024-10-10
  • Java中的接口和抽象類(lèi)用法實(shí)例詳解

    Java中的接口和抽象類(lèi)用法實(shí)例詳解

    這篇文章主要介紹了Java中的接口和抽象類(lèi)用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Java中關(guān)于接口和抽象類(lèi)的概念、定義、用法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2015-12-12
  • SpringBoot HTTP 400排查方式

    SpringBoot HTTP 400排查方式

    這篇文章主要介紹了SpringBoot HTTP 400排查方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • java反射拼接方法名動(dòng)態(tài)執(zhí)行方法實(shí)例

    java反射拼接方法名動(dòng)態(tài)執(zhí)行方法實(shí)例

    下面小編就為大家?guī)?lái)一篇java反射拼接方法名動(dòng)態(tài)執(zhí)行方法實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-08-08

最新評(píng)論

利辛县| 沙雅县| 巴林右旗| 长丰县| 陵水| 白沙| 闵行区| 麦盖提县| 宣武区| 廊坊市| 芮城县| 胶南市| 呈贡县| 岳阳县| 东乌珠穆沁旗| 弥勒县| 扶风县| 哈密市| 广安市| 镇原县| 淮南市| 寿光市| 安溪县| 调兵山市| 顺昌县| 甘南县| 景谷| 浦县| 鄂托克旗| 碌曲县| 崇明县| 湟中县| 绍兴市| 井陉县| 湘潭县| 尚义县| 时尚| 凤庆县| 天镇县| 红安县| 墨脱县|