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

Java深入了解數(shù)據(jù)結(jié)構(gòu)之優(yōu)先級隊列(堆)

 更新時間:2022年01月27日 15:27:50   作者:/少司命  
普通的隊列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),元素在隊列尾追加,而從隊列頭刪除。在優(yōu)先隊列中,元素被賦予優(yōu)先級。當(dāng)訪問元素時,具有最高優(yōu)先級的元素最先刪除。優(yōu)先隊列具有最高級先出 (first in, largest out)的行為特征。通常采用堆數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)

一,二叉樹的順序存儲

①存儲方式

使用數(shù)組保存二叉樹結(jié)構(gòu),方式即將二叉樹用層序遍歷方式放入數(shù)組中。 一般只適合表示完全二叉樹,因為非完全二叉樹會有空間的浪費。 這種方式的主要用法就是堆的表示。

②下標(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;

③二叉樹順序遍歷

// 層序遍歷
    void levelOrderTraversal(TreeNode root) {
        if(root == null) {
            return;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode top = queue.poll();
            System.out.print(top.val+" ");
            if(top.left != null) {
                queue.offer(top.left);
            }
            if(top.right!=null) {
                queue.offer(top.right);
            }
        }
        System.out.println();
    }

二,堆

①概念

1. 堆邏輯上是一棵完全二叉樹

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

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

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

②操作-向下調(diào)整

前提:

左右子樹必須已經(jīng)是一個堆,才能調(diào)整。

說明:

1. array 代表存儲堆的數(shù)組

2. size 代表數(shù)組中被視為堆數(shù)據(jù)的個數(shù)

3. index 代表要調(diào)整位置的下標(biāo)

4. left 代表 index 左孩子下標(biāo)

5. right 代表 index 右孩子下標(biāo)

6. min 代表 index 的最小值孩子的下標(biāo)?

過程(以小堆為例):

Ⅰ index 如果已經(jīng)是葉子結(jié)點,則整個調(diào)整過程結(jié)束

1. 判斷 index 位置有沒有孩子

2. 因為堆是完全二叉樹,沒有左孩子就一定沒有右孩子,所以判斷是否有左孩子

3. 因為堆的存儲結(jié)構(gòu)是數(shù)組,所以判斷是否有左孩子即判斷左孩子下標(biāo)是否越界,即 left >= size 越界

Ⅱ 確定 left 或 right,誰是 index 的最小孩子 min

1. 如果右孩子不存在,則 min = left

2. 否則,比較 array[left] 和 array[right] 值得大小,選擇小的為 min

Ⅲ比較 array[index] 的值 和 array[min] 的值,如果 array[index] <= array[min],則滿足堆的性質(zhì),調(diào)整結(jié)束

Ⅳ否則,交換 array[index] 和 array[min] 的值

Ⅴ然后因為 min 位置的堆的性質(zhì)可能被破壞,所以把 min 視作 index,向下重復(fù)以上過程

向下調(diào)整是以層序遍歷的二叉樹為例來遍歷

public void adjustDown(int root,int len){
        int parent = root;
        int child = 2*parent + 1;
        while(child < len){
            if (child + 1 < len && this.elem[child] < this.elem[child + 1] ){
                child++;
            }
            if(this.elem[child] > this.elem[parent]){
                int tmp = this.elem[parent];
                this.elem[parent] = this.elem[child];
                this.elem[child] = tmp;
                parent = child;
                child = 2*parent + 1;
            }else{
                break;
            }
        }
    }

③建堆(建大堆為例)

下面我們給出一個數(shù)組,這個數(shù)組邏輯上可以看做一顆完全二叉樹,但是還不是一個堆,現(xiàn)在我們通過算法,把它構(gòu) 建成一個堆。根節(jié)點左右子樹不是堆,我們怎么調(diào)整呢?這里我們從倒數(shù)的第一個非葉子節(jié)點的子樹開始調(diào)整,一直 調(diào)整到根節(jié)點的樹,就可以調(diào)整成堆。

//建大堆
    public void creatHeap(int[] array){
        for (int i = 0; i < array.length;i++){
            this.elem[i] = array[i];
            suedSize++;
        }
        for (int parent = (array.length - 1 - 1) / 2;parent >= 0;parent--){
            adjustDown(parent,this.suedSize);
        }

三,堆的應(yīng)用-優(yōu)先級隊列

①概念

在很多應(yīng)用中,我們通常需要按照優(yōu)先級情況對待處理對象進(jìn)行處理,比如首先處理優(yōu)先級最高的對象,然后處理次 高的對象。最簡單的一個例子就是,在手機上玩游戲的時候,如果有來電,那么系統(tǒng)應(yīng)該優(yōu)先處理打進(jìn)來的電話。 在這種情況下,我們的數(shù)據(jù)結(jié)構(gòu)應(yīng)該提供兩個最基本的操作,一個是返回最高優(yōu)先級對象,一個是添加新的對象。這 種數(shù)據(jù)結(jié)構(gòu)就是優(yōu)先級隊列(Priority Queue)

②內(nèi)部原理

優(yōu)先級隊列的實現(xiàn)方式有很多,但最常見的是使用堆來構(gòu)建。

③入隊列

過程(以大堆為例):

1. 首先按尾插方式放入數(shù)組

2. 比較其和其雙親的值的大小,如果雙親的值大,則滿足堆的性質(zhì),插入結(jié)束

3. 否則,交換其和雙親位置的值,重新進(jìn)行 2、3 步驟 4. 直到根結(jié)點

public void adjustUp(int child){
        int parent = (child - 1) / 2;
        while(child>0){
            if(this.elem[child] > this.elem[parent]){
                int tmp = this.elem[parent];
                this.elem[parent] = this.elem[child];
                this.elem[child] = tmp;
                child = parent;
                parent = (child - 1) / 2;
            }else {
                break;
            }
        }
    }
public void push(int val) {
        if (isFull()) {
            this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);
            this.elem[this.suedSize] = val;
            this.suedSize++;
            adjustUp(this.suedSize - 1);
 
        }
    }

④出隊列(優(yōu)先級最高)

為了防止破壞堆的結(jié)構(gòu),刪除時并不是直接將堆頂元素刪除,而是用數(shù)組的最后一個元素替換堆頂元素,然后通過向下調(diào)整方式重新調(diào)整成堆

 public boolean isEmpty(){
        return this.suedSize == 0;
    }
 public void pop(){
        if(isEmpty()){
            return;
        }
        int tmp = this.elem[0];
        this.elem[0] = this.elem[this.suedSize-1];
        this.elem[this.suedSize-1] = tmp;
        this.suedSize--;
        adjustDown(0,this.suedSize);
    }

⑤返回隊首元素(優(yōu)先級最高)

public int peek(){
        if(isEmpty()){
            return -1;
        }
        return this.elem[0];
    }
  public boolean isFull(){
        return this.suedSize == this.elem.length;
    }

四,堆排序

 /**
     * 一定是先創(chuàng)建大堆
     *      調(diào)整每棵樹
     * 開始堆排序:
     *     先交換  后調(diào)整  直到 0下標(biāo)
     */
 
    public void heapSort(){
        int end = this.suedSize-1;
        while (end > 0){
            int tmp = this.elem[0];
            this.elem[0] = this.elem[end];
            this.elem[end] = tmp;
            adjustDown(0,end);
            end--;
 
        }
 
    }

到此這篇關(guān)于Java深入了解數(shù)據(jù)結(jié)構(gòu)之優(yōu)先級隊列(堆)的文章就介紹到這了,更多相關(guān)Java 優(yōu)先級隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解java中的Collections類

    詳解java中的Collections類

    這篇文章主要為大家詳細(xì)介紹了java中的Collections類,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Java for循環(huán)性能優(yōu)化實現(xiàn)解析

    Java for循環(huán)性能優(yōu)化實現(xiàn)解析

    這篇文章主要介紹了Java for循環(huán)性能優(yōu)化實現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • Java利用Map實現(xiàn)計算文本中字符個數(shù)

    Java利用Map實現(xiàn)計算文本中字符個數(shù)

    這篇文章主要為大家詳細(xì)介紹了Java如何利用Map集合實現(xiàn)計算文本中字符個數(shù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-08-08
  • 利用Java異常機制實現(xiàn)模擬借書系統(tǒng)

    利用Java異常機制實現(xiàn)模擬借書系統(tǒng)

    這篇文章主要給大家介紹了利用Java異常機制實現(xiàn)模擬借書系統(tǒng)的相關(guān)資料,文中先對java異常機制進(jìn)行了簡單介紹,而后通過示例代碼介紹了java語言是如何實現(xiàn)一個控制臺版的模擬借書系統(tǒng),需要的朋友可以參考學(xué)習(xí),一起來看看吧。
    2017-04-04
  • SpringBoot yaml語法與數(shù)據(jù)讀取操作詳解

    SpringBoot yaml語法與數(shù)據(jù)讀取操作詳解

    YAML 是 “YAML Ain’t Markup Language”(YAML 不是一種標(biāo)記語言)的遞歸縮寫。在開發(fā)的這種語言時,YAML 的意思其實是:“Yet Another Markup Language”(仍是一種標(biāo)記語言),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • TKmybatis的框架介紹和原理解析

    TKmybatis的框架介紹和原理解析

    tkmybatis是在mybatis框架的基礎(chǔ)上提供了很多工具,讓開發(fā)更加高效,下面來看看這個框架的基本使用,后面會對相關(guān)源碼進(jìn)行分析,感興趣的同學(xué)可以看一下,挺不錯的一個工具
    2020-12-12
  • 最新評論

    徐州市| 和政县| 马鞍山市| 焦作市| 喀喇| 洮南市| 安塞县| 延寿县| 彭山县| 台南市| 扶余县| 赞皇县| 建宁县| 鄄城县| 新野县| 贵定县| 柘荣县| 隆尧县| 岳普湖县| 宜君县| 铅山县| 阿鲁科尔沁旗| 吉林省| 朝阳区| 会宁县| 凯里市| 乌兰察布市| 苍南县| 阿图什市| 泰宁县| 米脂县| 黄石市| 商洛市| 泰宁县| 信阳市| 古浪县| 油尖旺区| 江西省| 遂川县| 陵川县| 亚东县|