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

Java堆&優(yōu)先級(jí)隊(duì)列示例講解(上)

 更新時(shí)間:2022年03月18日 11:24:47   作者:愛(ài)干飯的猿  
這篇文章主要通過(guò)示例詳細(xì)為大家介紹Java中的堆以及優(yōu)先級(jí)隊(duì)列,文中的示例代碼講解詳細(xì),對(duì)我們了解java有一定幫助,需要的可以參考一下

1. 二叉樹(shù)的順序存儲(chǔ)

1.1 存儲(chǔ)方式

使用數(shù)組保存二叉樹(shù)結(jié)構(gòu),方式即將二叉樹(shù)用 層序遍歷 方式放入數(shù)組中。

一般只適合表示完全二叉樹(shù),這種方式的主要用法就是堆的表示。

因?yàn)榉峭耆鏄?shù)會(huì)有空間的浪費(fèi)(所有非完全二叉樹(shù)用鏈?zhǔn)酱鎯?chǔ))。

1.2 下標(biāo)關(guān)系

已知雙親 (parent) 的下標(biāo),則:

左孩子 (left) 下標(biāo) = 2 * parent + 1;

右孩子 (right) 下標(biāo) = 2 * parent + 2;

已知孩子(不區(qū)分左右) (child) 下標(biāo),則:

雙親 (parent) 下標(biāo) = (child - 1) / 2;

2. 堆(heap)

2.1 概念

1. 堆邏輯上是一棵完全二叉樹(shù)

2. 堆物理上是保存在數(shù)組中

3. 滿足任意結(jié)點(diǎn)的值都大于其子樹(shù)中結(jié)點(diǎn)的值,叫做大堆,或者大根堆,或者最大堆

4. 反之,則是小堆,或者小根堆,或者最小堆

5. 堆的基本作用是,快速找集合中的 最值

2.2 操作-(下沉&上?。┍纠亲畲蠖?/h3>

元素下沉:

     /**
     * 下沉操作
     */
    public void siftDown(int k){
        //還存在子樹(shù)
        while (leftChild(k) < data.size()){
            int j = leftChild(k);
            //判斷是否存在右子樹(shù)且大于左子樹(shù)的值
            if(j+1 < data.size() && data.get(j+1) > data.get(j)){
                j=j+1;
            }
            //此時(shí)j為左右子樹(shù)最大值
            //和當(dāng)前節(jié)點(diǎn)比較大小
            if(data.get(j) <= data.get(k)){
                break;
            }else {
                swap(k,j);
                k=j;
            }
        }
    }

元素上?。?/p>

    /**
     * 上浮操作
     */
    // 上浮操作的終止條件: 已經(jīng)走到根節(jié)點(diǎn) || 當(dāng)前節(jié)點(diǎn)值 <= 父節(jié)點(diǎn)值
    // 循環(huán)的迭代條件 : 還存在父節(jié)點(diǎn)并且當(dāng)前節(jié)點(diǎn)值 > 父節(jié)點(diǎn)值
    private void siftUp(int k) {
        while (k>0 && data.get(k)>data.get(parent(k))){
            swap(k,parent(k));
            k=parent(k);
        }
    }

其中swap方法是交換操作:

    //交換三連
    private void swap(int i,int j) {
        int temp = data.get(j);
        data.set(j,data.get(i));
        data.set(i,temp);
    }

堆化數(shù)組:

    /**
     * 將任意數(shù)組堆化
     * @param arr
     */
    public MaxHeap(int[] arr){
        data = new ArrayList<>(arr.length);
        // 1.先將arr的所有元素復(fù)制到data數(shù)組中
        for(int i : arr){
            data.add(i);
        }
        // 2.從最后一個(gè)非葉子結(jié)點(diǎn)開(kāi)始進(jìn)行siftDown
        for (int i = parent(data.size()-1); i >=0 ; i--) {
            siftDown(i);
        }
    }

圖示:

以此數(shù)組為例:

// 調(diào)整前
int[] array = { 27,15,19,18,28,34,65,49,25,37 };
// 調(diào)整后
int[] array = { 15,18,19,25,28,34,65,49,27,37 };

時(shí)間復(fù)雜度分析:

最壞的情況即圖示的情況,從根一路比較到葉子,比較的次數(shù)為完全二叉樹(shù)的高度

即時(shí)間復(fù)雜度為 O(log(n))

2.3 建堆-完整代碼(最大堆)

/**
 * 基于整形最大堆實(shí)現(xiàn)
 * 時(shí)根節(jié)點(diǎn)從0開(kāi)始編號(hào),若此時(shí)節(jié)點(diǎn)編號(hào)為k
 * 左孩子為2k+1
 * 右孩子為2k+2
 * 父節(jié)點(diǎn)為(k-1)/2
 */
 
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
 
public class MaxHeap {
    // 使用JDK的動(dòng)態(tài)數(shù)組(ArrayList)來(lái)存儲(chǔ)一個(gè)最大堆
    List<Integer> data;
 
    // 構(gòu)造方法的this調(diào)用
    public MaxHeap(){
        this(10);
    }
    
    // 初始化的堆大小
    public MaxHeap(int size){
        data = new ArrayList<>(size);
    }
 
    /**
     * 將任意數(shù)組堆化
     * @param arr
     */
    public MaxHeap(int[] arr){
        data = new ArrayList<>(arr.length);
        // 1.先將arr的所有元素復(fù)制到data數(shù)組中
        for(int i : arr){
            data.add(i);
        }
        // 2.從最后一個(gè)非葉子結(jié)點(diǎn)開(kāi)始進(jìn)行siftDown
        for (int i = parent(data.size()-1); i >=0 ; i--) {
            siftDown(i);
        }
    }
 
    /**
     * 向最大堆中增加值為Value的元素
     * @param value
     */
    public void add(int value){
        //1.先直接加到堆的末尾
        data.add(value);
        //2.元素上浮操作
        siftUp(data.size()-1);
    }
 
    /**
     * 只找到堆頂元素值
     * @return
     */
    public int peekMax (){
        if(isEmpty()){
            throw new NoSuchElementException("heap is empty!connot peek");
        }
        return data.get(0);
    }
 
    /**
     * 取出當(dāng)前最大堆的最大值
     */
    public int extractMax(){
        // 取值一定注意判空
        if(isEmpty()){
            throw new NoSuchElementException("heap is empty!connot extract");
        }
        int max = data.get(0);
        // 1.將數(shù)組末尾元素頂?shù)蕉秧?
        int lastValue =data.get(data.size()-1);
        data.set(0,lastValue);
        // 2.將數(shù)組末尾的元素刪除
        data.remove(data.size()-1);
        // 3.進(jìn)行元素的下沉操作
        siftDown(0);
        return max;
    }
 
    /**
     * 下沉操作
     */
    public void siftDown(int k){
        //還存在子樹(shù)
        while (leftChild(k) < data.size()){
            int j = leftChild(k);
            //判斷是否存在右子樹(shù)且大于左子樹(shù)的值
            if(j+1 < data.size() && data.get(j+1) > data.get(j)){
                j=j+1;
            }
            //此時(shí)j為左右子樹(shù)最大值
            //和當(dāng)前節(jié)點(diǎn)比較大小
            if(data.get(j) <= data.get(k)){
                break;
            }else {
                swap(k,j);
                k=j;
            }
        }
    }
 
    /**
     * 上浮操作
     */
    // 上浮操作的終止條件: 已經(jīng)走到根節(jié)點(diǎn) || 當(dāng)前節(jié)點(diǎn)值 <= 父節(jié)點(diǎn)值
    // 循環(huán)的迭代條件 : 還存在父節(jié)點(diǎn)并且當(dāng)前節(jié)點(diǎn)值 > 父節(jié)點(diǎn)值
    private void siftUp(int k) {
        while (k>0 && data.get(k)>data.get(parent(k))){
            swap(k,parent(k));
            k=parent(k);
        }
    }
 
    //交換三連
    private void swap(int i,int j) {
        int temp = data.get(j);
        data.set(j,data.get(i));
        data.set(i,temp);
    }
 
    //判讀堆為空
    public boolean isEmpty(){
        return data.size() == 0;
    }
    //根據(jù)索引找父節(jié)點(diǎn)
    public int parent(int k){
        return (k-1)>>1;
    }
    //根據(jù)索引找左孩子
    public int leftChild(int k){
        return k<<2+1;
    }
    //根據(jù)索引找右孩子
    public int rightChild(int k){
        return k<<2+2;
    }
 
    @Override
    public String toString() {
        return data.toString();
    }
}

ps:隨機(jī)數(shù)操作

        int[] data=new int[10000];
        //隨機(jī)數(shù)
        ThreadLocalRandom random = ThreadLocalRandom.current();
        for (int i = 0; i < data.length; i++) {
            data[i] = random.nextInt();
        }

3. 優(yōu)先級(jí)隊(duì)列

詳見(jiàn)下節(jié):Java堆&優(yōu)先級(jí)隊(duì)列示例講解(下)

到此這篇關(guān)于Java堆&優(yōu)先級(jí)隊(duì)列示例講解(上)的文章就介紹到這了,更多相關(guān)Java 堆 優(yōu)先級(jí)隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Java實(shí)現(xiàn)簡(jiǎn)單貪吃蛇游戲

    基于Java實(shí)現(xiàn)簡(jiǎn)單貪吃蛇游戲

    這篇文章主要為大家詳細(xì)介紹了基于Java實(shí)現(xiàn)簡(jiǎn)單貪吃蛇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • java實(shí)現(xiàn)微信點(diǎn)餐申請(qǐng)微信退款

    java實(shí)現(xiàn)微信點(diǎn)餐申請(qǐng)微信退款

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信點(diǎn)餐申請(qǐng)微信退款,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • 如何在Maven項(xiàng)目配置pom.xml指定JDK版本和編碼

    如何在Maven項(xiàng)目配置pom.xml指定JDK版本和編碼

    maven是個(gè)項(xiàng)目管理工具,如果我們不告訴它要使用什么樣的jdk版本編譯,它就會(huì)用maven-compiler-plugin默認(rèn)的jdk版本來(lái)處理,這樣就容易出現(xiàn)版本不匹配的問(wèn)題,這篇文章主要給大家介紹了關(guān)于如何在Maven項(xiàng)目配置pom.xml指定JDK版本和編碼的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • 淺談java異常處理(父子異常的處理)

    淺談java異常處理(父子異常的處理)

    下面小編就為大家?guī)?lái)一篇淺談java異常處理(父子異常的處理)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-09-09
  • 基于java中stack與heap的區(qū)別,java中的垃圾回收機(jī)制的相關(guān)介紹

    基于java中stack與heap的區(qū)別,java中的垃圾回收機(jī)制的相關(guān)介紹

    本篇文章小編將為大家介紹,基于java中stack與heap的區(qū)別,java中的垃圾回收機(jī)制的相關(guān)介紹,需要的可以參考一下
    2013-04-04
  • Java Spring使用hutool的HttpRequest發(fā)送請(qǐng)求的幾種方式

    Java Spring使用hutool的HttpRequest發(fā)送請(qǐng)求的幾種方式

    文章介紹了Hutool庫(kù)中用于發(fā)送HTTP請(qǐng)求的工具,包括添加依賴、發(fā)送GET和POST請(qǐng)求的方法,以及GET請(qǐng)求的不同參數(shù)傳遞方式,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Java樹(shù)形結(jié)構(gòu)遞歸查詢方式

    Java樹(shù)形結(jié)構(gòu)遞歸查詢方式

    文章介紹了Java中實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)遞歸查詢的方法,首先找出所有的根節(jié)點(diǎn),然后通過(guò)循環(huán)遍歷根節(jié)點(diǎn),找到每個(gè)根節(jié)點(diǎn)的子節(jié)點(diǎn),最終構(gòu)建完整的樹(shù)形結(jié)構(gòu),這是一種有效的遞歸查詢思路,適用于需要層次化展示數(shù)據(jù)的場(chǎng)景
    2024-12-12
  • MyBatis-Plus攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限控制的方法

    MyBatis-Plus攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限控制的方法

    MyBatis-Plus是一款基于MyBatis的增強(qiáng)工具,它提供了一些便捷的功能和增強(qiáng)的查詢能力,數(shù)據(jù)權(quán)限控制是在系統(tǒng)中對(duì)用戶訪問(wèn)數(shù)據(jù)進(jìn)行限制的一種機(jī)制,這篇文章主要給大家介紹了關(guān)于MyBatis-Plus攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限控制的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • Spring Cache的使用示例詳解

    Spring Cache的使用示例詳解

    SpringCache是構(gòu)建在SpringContext基礎(chǔ)上的緩存實(shí)現(xiàn),提供了多種緩存注解,如@Cachable、@CacheEvict、@CachePut等,本文通過(guò)實(shí)例代碼介紹了Spring Cache的使用,感興趣的朋友一起看看吧
    2025-01-01
  • IDEA在plugins里搜不到mybatisx插件的解決方法

    IDEA在plugins里搜不到mybatisx插件的解決方法

    本文主要介紹了IDEA在plugins里搜不到mybatisx插件的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06

最新評(píng)論

珠海市| 纳雍县| 包头市| 万州区| 福海县| 北安市| 台北市| 徐闻县| 霸州市| 托里县| 玉环县| 芜湖县| 竹山县| 修武县| 施秉县| 崇州市| 定西市| 麦盖提县| 淄博市| 新邵县| 福州市| 忻城县| 潜山县| 平泉县| 遂溪县| 抚松县| 师宗县| 谢通门县| 绥阳县| 邵武市| 静安区| 治多县| 宜阳县| 报价| 上蔡县| 鲜城| 陆良县| 通道| 辉县市| 沙坪坝区| 喀喇沁旗|