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

Java數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之棧和隊(duì)列

 更新時(shí)間:2021年05月07日 09:32:00   作者:愿美夢成真  
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之棧和隊(duì)列,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有一定的幫助,需要的朋友可以參考下

一、棧

1.1 概述

Java為什么要有集合類: 臨時(shí)存儲(chǔ)數(shù)據(jù)。
鏈表的本質(zhì): 對象間通過持有和引用關(guān)系互相關(guān)聯(lián)起來。

線性表: 普通線性表, 操作受限線性表(某些操作受到限制 --> 某一個(gè)線性表它的增刪改操作受到限制) --> 棧 & 隊(duì)列

1.1.1 線性表的概念

(1)線性表:n個(gè)數(shù)據(jù)元素的有序序列。

①首先,線性表中元素的個(gè)數(shù)是有限的。
②其次,線性表中元素是有序的。

(2)那這個(gè)”序”指的是什么呢?

除表頭和表尾元素外,其它元素都有唯一前驅(qū)和唯一后繼,其唯一前驅(qū)或唯一后繼確定了該元素在線性表中的位置。
②因此,線性表中,每個(gè)數(shù)據(jù)元素都有一個(gè)確定的位序,這個(gè)確定的位序我們稱之為索引。 表頭元素有唯一后繼,無前驅(qū),表尾元素有唯一前驅(qū),無后繼。

1.1.2 棧的概念

棧是一種”操作受限”的線性表,體現(xiàn)在只能在一端插入和刪除數(shù)據(jù),符合FILO的特性。

FILO: 先進(jìn)后出,
LIFO: 后進(jìn)先出

1.1.3 棧的應(yīng)用

在這里插入圖片描述

線性表和哈希表在以后工作中會(huì)最常用。
棧在實(shí)際工作中不常用

應(yīng)用場景:

1.函數(shù)調(diào)用棧
2.反序字符串: 實(shí)現(xiàn)reNumber(str)方法,反轉(zhuǎn)字符串(附代碼) 。

public class DemoStack1 {
    public static void main(String[] args) {

        String str = "123456789";
        String reStr = reStr(str);
        System.out.println(reStr);

    }

    // 棧先進(jìn)后出
    public static String reStr(String str){
        MyArrayStack<Character> stack = new MyArrayStack<>();

        for (int i = 0; i < str.length(); i++) {
            stack.push(str.charAt(i));
        }

        StringBuffer buffer = new StringBuffer();

        // 1 2 3 4 5 6 7 8 9
        while (!stack.isEmpty()){
            Character pop = stack.pop();
            buffer.append(pop);
        }

        return buffer.toString();
    }
}

3.括號(hào)匹配問題: 實(shí)現(xiàn)judgeBracket(str)方法來判斷括號(hào)匹配 (附代碼)。

public class DemoStack2 {
    public static void main(String[] args) {

        String str = "public class) DemoStack2 {public static void main(String[] args) {}}";

        boolean bool = judgeBracket(str);
        System.out.println(bool);

    }

    public static  boolean judgeBracket(String str){
        MyArrayStack<Character> stack = new MyArrayStack<>();

        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            // 判斷c 是left括號(hào), 然后入棧

            if (c == '{'){
                stack.push('}');
            } else if (c == '['){
                stack.push(']');
            }else if (c == '('){
                stack.push(')');
            } else if (c == '}' || c == ')' || c == ']'){
                Character pop = stack.pop();
                if (c != pop){// 不匹配
                    return false;
                }
            }
        }

        return stack.isEmpty();
    }
}

4.編譯器利用棧實(shí)現(xiàn)表達(dá)式求值

5.瀏覽器的前進(jìn)后退功能

6. 利用棧實(shí)現(xiàn) DFS: depth-first-search 深度優(yōu)先遍歷(樹 圖)

編譯器利用棧實(shí)現(xiàn)表達(dá)式求值

中綴表達(dá)式: 2 + 3 * 2 給人看的 , 運(yùn)算符放到中間
前綴表達(dá)式: + 2 * 3 2 運(yùn)算符放到之前
后綴表達(dá)式: 2 3 2 * + 運(yùn)算符放到后面

// 中綴表達(dá)式轉(zhuǎn)化為后綴:
// 遍歷中綴表達(dá)式
// 遇到操作數(shù)輸出
// 遇到操作符, 出棧, 直到遇到更低優(yōu)先級的操作符, 操作符入棧
// 遍歷完成, 全部彈棧

// 中綴表達(dá)式轉(zhuǎn)化為前綴:
// 遍歷中綴表達(dá)式: 逆序遍歷
// 遇到操作數(shù)輸出: 頭插法
// 遇到操作符, 出棧, 只彈出更高優(yōu)先級的操作符, 操作符入棧
// 遍歷完成, 全部彈棧

二、隊(duì)列

2.1 隊(duì)列的概念

隊(duì)列也是一種”操作受限”的線性表,體現(xiàn)在一端插入數(shù)據(jù)在另一端刪除數(shù)據(jù),特性是FIFO。

在這里插入圖片描述

2.2 隊(duì)列的實(shí)現(xiàn)

實(shí)現(xiàn)一個(gè)集合類
集合類: 數(shù)據(jù)容器
底層: 數(shù)組 or 鏈表
數(shù)據(jù)結(jié)構(gòu)表現(xiàn): 隊(duì)列

(1)用數(shù)組實(shí)現(xiàn)一個(gè)隊(duì)列。

/**
 * 用數(shù)組實(shí)現(xiàn)一個(gè)隊(duì)列
 * 集合類角度: 數(shù)據(jù)容器
 * 底層: 數(shù)組
 * 表示: 隊(duì)列
 */
public class MyArrayQueue <T> {

    private final int MAX_CAPACITY = Integer.MAX_VALUE - 8;
    private final int INIT_CAPACITY = 16;

    private Object[] objs;
    private int size;
    private int head;// 頭的下標(biāo)
    private int end;// 尾的下標(biāo)


    public MyArrayQueue(){
        objs = new Object[INIT_CAPACITY];
    }
    public MyArrayQueue(int initCapcity){
        if (initCapcity <= 0 || initCapcity > MAX_CAPACITY) throw new IllegalArgumentException("" + initCapcity);

        objs = new Object[initCapcity];
    }

    public boolean offer(T t){
        // 如果數(shù)組滿了
        if (size == objs.length){
            int newLen = getLen();
            grow(newLen);
        }

        // 可以添加
        if (isEmpty()){
            // 沒有任何元素存儲(chǔ): 新添加的元素就是唯一的元素
            objs[head] = t;
            end = head;
            size++;
            return true;
        } else {
            // 原本存儲(chǔ)就有內(nèi)容

            // 尾后移一位
            end = (end + 1) % objs.length;
            objs[end] = t;
            size++;
            return true;
        }
    }

    private void grow(int newLen) {
        Object[] newArr = new Object[newLen];
        for (int i = 0; i < objs.length; i++) {
            int index = (head + i) % objs.length;

            newArr[i] = objs[index];
        }
        objs = newArr;
        head = 0;
        end = size - 1;
    }

    private int getLen() {
        int oldLen = objs.length;
        int newLen = oldLen << 1;
        // 判斷新長度是否溢出
        if (newLen <= 0 || newLen > MAX_CAPACITY){
            newLen = MAX_CAPACITY;
        }
        // 如果新長度和舊長度一樣
        if (newLen == oldLen)throw  new RuntimeException("stack can not add");

        return newLen;
    }


    public T poll(){
        if (isEmpty()) throw new RuntimeException("queue is empty");

        if (size == 1){
            // 原隊(duì)列中只剩一個(gè)元素
            T oldValue = (T)objs[head];
            head = 0;
            end = 0;
            size--;
            return oldValue;
        } else {
            // 隊(duì)列中超過一個(gè)元素
            T oldValue = (T)objs[head];
            head = (head + 1) % objs.length;
            size--;
            return oldValue;
        }
    }

    public T peek(){
        if (isEmpty()) throw new RuntimeException("queue is empty");
        return (T)objs[head];
    }

    public int size() {
        return size;
    }

    public boolean isEmpty(){
        return size == 0;
    }
}

(2)用鏈表實(shí)現(xiàn)一個(gè)鏈表。

public class MyLinkedQueue <T> {

    private Node head;// 隊(duì)頭
    private Node end; // 隊(duì)尾
    private int size;

    // 添加 offer
    // 刪除 poll
    // 查看隊(duì)頭元素 peek

    public  boolean offer(T t){

        // 如果原隊(duì)列為空
        if (isEmpty()){// 原隊(duì)列空
            // 讓頭尾都指向這個(gè)新加的結(jié)點(diǎn)
            head = new Node(t, null);
            end = head;
            size++;
            return true;
        }

        // 原隊(duì)列不空
        // 把這個(gè)元素添加到隊(duì)尾
        end.next = new Node(t, null);
        end = end.next;// end后移
        size++;
        return true;
    }

    public T poll(){
        if (isEmpty()) throw  new RuntimeException("queue is empty");

        if (size == 1){
            // 代表著, 鏈表中只有一個(gè)元素
            T oldVlaue = head.value;
            head = null;
            end = null;
            size--;
            return  oldVlaue;
        }else {
            T oldVlaue = head.value;
            head = head.next;
            size--;
            return oldVlaue;
        }
    }

    public T peek(){
        if (isEmpty()) throw  new RuntimeException("queue is empty");
        return head.value;
    }


    public boolean isEmpty(){
        return size == 0;
    }
    public int size(){
        return size;
    }




    class Node{
        T value;
        Node next;

        public Node(T value, Node next) {
            this.value = value;
            this.next = next;
        }
    }
}

2.3 隊(duì)列的應(yīng)用

(1)隊(duì)列更不常用(自己寫代碼使用不常用):

(2)常見, 很多jdk源碼, 中間件的源碼上 很多地方使用了隊(duì)列

Eg:

①生產(chǎn)者消費(fèi)者問題

生產(chǎn)者 – 消費(fèi)者
生產(chǎn)者: 廚師
消費(fèi)者: 吃面包的人
桌子: 放面包的地方

②線程池

線程池: 任務(wù)
生產(chǎn)者: 產(chǎn)生任務(wù)
消費(fèi)者: 線程
桌子: 隊(duì)列

③生態(tài)環(huán)境:

第三方輪子: 要看懂
Maven

④消息隊(duì)列和緩存。

(3)普通隊(duì)列的應(yīng)用場景是很有限的,一般在工程中用到的是阻塞隊(duì)列。

①阻塞隊(duì)列(有一個(gè)隊(duì)列, 大小一定):常用于生產(chǎn)者-消費(fèi)者模型中。
當(dāng)隊(duì)列滿的時(shí)候,入隊(duì)列就阻塞。
當(dāng)隊(duì)列空的時(shí)候,出隊(duì)列就阻塞。

②利用隊(duì)列實(shí)現(xiàn) BFS:breadth first search 廣度優(yōu)先搜索/ 遍歷 ()

到此這篇關(guān)于Java數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之棧和隊(duì)列的文章就介紹到這了,更多相關(guān)Java棧和隊(duì)列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)軟件運(yùn)行時(shí)啟動(dòng)信息窗口的方法

    Java實(shí)現(xiàn)軟件運(yùn)行時(shí)啟動(dòng)信息窗口的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)軟件運(yùn)行時(shí)啟動(dòng)信息窗口的方法,比較實(shí)用的功能,需要的朋友可以參考下
    2014-08-08
  • flowable動(dòng)態(tài)創(chuàng)建多級流程模板實(shí)現(xiàn)demo

    flowable動(dòng)態(tài)創(chuàng)建多級流程模板實(shí)現(xiàn)demo

    這篇文章主要為大家介紹了flowable動(dòng)態(tài)創(chuàng)建多級流程模板實(shí)現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 一個(gè)Java中BigDecimal的問題記錄

    一個(gè)Java中BigDecimal的問題記錄

    這篇文章主要給大家介紹了關(guān)于Java中一個(gè)BigDecimal問題的相關(guān)資料,通過文中介紹的方法可以很方便的解決BigDecimal進(jìn)行計(jì)算的時(shí)候不管怎么計(jì)算,最后得到的值都沒有變化的問題,需要的朋友可以參考下
    2021-11-11
  • MapStruct表達(dá)式應(yīng)用及避坑詳解

    MapStruct表達(dá)式應(yīng)用及避坑詳解

    一不小心踩了MapStruct表達(dá)式的坑,發(fā)現(xiàn)了一個(gè)在官方文檔上都找不到的功能,有必要記錄下。MapStruct是一個(gè)代碼生成器,它基于約定優(yōu)于配置的方法大大簡化了Java?Bean類型之間的映射的實(shí)現(xiàn)
    2022-02-02
  • Netty分布式行解碼器邏輯源碼解析

    Netty分布式行解碼器邏輯源碼解析

    這篇文章主要為大家介紹了Netty分布式行解碼器邏輯源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • spring注解識(shí)別一個(gè)接口的多個(gè)實(shí)現(xiàn)類方法

    spring注解識(shí)別一個(gè)接口的多個(gè)實(shí)現(xiàn)類方法

    下面小編就為大家?guī)硪黄猻pring注解識(shí)別一個(gè)接口的多個(gè)實(shí)現(xiàn)類方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • 詳解Java面試官最愛問的volatile關(guān)鍵字

    詳解Java面試官最愛問的volatile關(guān)鍵字

    這篇文章主要介紹了詳解Java面試官最愛問的volatile關(guān)鍵字,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • MyBatis-Plus不使用數(shù)據(jù)庫默認(rèn)值的問題及解決

    MyBatis-Plus不使用數(shù)據(jù)庫默認(rèn)值的問題及解決

    這篇文章主要介紹了MyBatis-Plus不使用數(shù)據(jù)庫默認(rèn)值的問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • MyBatis中<collection>標(biāo)簽的多種用法

    MyBatis中<collection>標(biāo)簽的多種用法

    collection標(biāo)簽是處理一對多關(guān)系的關(guān)鍵工具,它能夠?qū)⒉樵兘Y(jié)果巧妙地映射到Java對象的集合屬性中,本文主要介紹了MyBatis中<collection>標(biāo)簽的多種用法,感興趣的可以了解一下
    2025-04-04
  • Java使用connectTo方法提高代碼可續(xù)性詳解

    Java使用connectTo方法提高代碼可續(xù)性詳解

    這篇文章主要介紹了Java使用connectTo方法提高代碼可續(xù)性,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評論

普格县| 舟山市| 革吉县| 萝北县| 石嘴山市| 土默特左旗| 宁晋县| 芷江| 霍邱县| 扬中市| 万载县| 吉木乃县| 饶平县| 阳江市| 公安县| 长汀县| 错那县| 丰城市| 冀州市| 紫云| 石家庄市| 墨玉县| 江北区| 长子县| 延庆县| 布尔津县| 蒙山县| 土默特左旗| 思茅市| 卓资县| 巴彦淖尔市| 黎平县| 汨罗市| 阿图什市| 韩城市| 苍溪县| 永兴县| 芦溪县| 临海市| 临夏市| 中宁县|