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

Java?超詳細講解數(shù)據(jù)結構中的堆的應用

 更新時間:2022年04月01日 17:44:22   作者:Pretend..  
堆首先是一個完全二叉樹,堆分為小根堆和大根堆。小根堆,所有結點的左右子節(jié)點都不小于根節(jié)點;大根堆,所有結點的左右子節(jié)點都不大于根節(jié)點。優(yōu)先級隊列(priorityQueue)底層就是一個小根堆

一、堆的創(chuàng)建

1、向下調整(以小堆為例)  

讓parent標記需要調整的節(jié)點,child標記parent的左孩子(注意:parent如果有孩子一定先是有左孩子)

如果parent的左孩子存在,即:child < size, 進行以下操作,直到parent的左孩子不存在:

  • parent右孩子是否存在,存在找到左右孩子中最小的孩子,讓child進行標記
  • 將parent與較小的孩子child比較,如果:

parent小于較小的孩子child,調整結束否則:交換parent與較小的孩子child,交換完成之后,parent中大的元素向下移動,可能導致子樹不滿足堆的性質,因此需要繼續(xù)向下調整,即parent = child;child = parent*2+1; 然后繼續(xù)2。

public void shiftDown(int[] elem,int parent,int len){
        int cur=parent*2+1;
        while(cur<len){
           if(cur+1<len){
               if(elem[cur+1]<elem[cur]){
                   cur++;
               }
           }
            if(this.elem[cur]<this.elem[parent]) {
                swap(cur, parent);
            }
            parent=cur;
            cur=parent*2+1;
        }
    }

2、創(chuàng)建堆

對于普通序列,我們需要從它的第一個有左節(jié)點的父節(jié)點開始調整,知道整棵樹滿足堆的性質。

3、創(chuàng)建堆的時間復雜度

堆必須是完全二叉樹,滿二叉樹也是完全二叉樹。由下面的計算,創(chuàng)建堆的時間復雜度為O(n).

 二、堆的插入和刪除

1、堆的插入

  • 將要插入的元素放在堆的最后,如果放不了,進行擴容
  • 將新插入的節(jié)點向上調整,直到滿足堆的性質

 【向上調整】

public void shiftUp(int elem[],int child){
        int parent=(child-1)/2;
        while(parent>=0){
            if(elem[child]>elem[parent]){
                swap(child,parent);
                child=parent;
                parent=(child-1)/2;
            }else{
                break;
            }
        }
    }

2、堆的刪除

根據(jù)堆的性質,對刪除的一定是堆頂元素。步驟如下:

  • 將堆頂元素和最后一個元素交換
  • 堆的元素個數(shù)減一
  • 對堆頂元素進行向下調整

 三、堆的應用

1、堆排序

升序:創(chuàng)建大根堆

降序:創(chuàng)建小根堆

交換堆頂元素和堆得最后一個元素,進行向下調整,直到堆有序。

2、top-k問題(求最小的K個數(shù))

top-k問題:求數(shù)據(jù)集合中前k個大或者小的元素,一般數(shù)據(jù)量都比較大。

class Solution {
    public int[] smallestK(int[] arr, int k) {
        int[] array=new int[k];
        if(arr==null||arr.length<=k||k==0){
            return array;
        }
        PriorityQueue<Integer> queue=new PriorityQueue<>((a,b)->b-a);
        int i=0;
        for(;i<k;++i){
            queue.offer(arr[i]);
        }
        while(i<arr.length){
            if(arr[i]<queue.peek()){
                queue.poll();
                queue.offer(arr[i]);
            }
            i++;
        }
        int size=queue.size();
        for(int j=0;j<size;++j){
            array[j]=queue.poll();
        }
        return array;
    }
}

四、常用接口的介紹

1、PriorityQueue的特性

Java集合框架中提供了PriorityQueue和PriorityBlockingQueue兩種類型的優(yōu)先級隊列。PriorityQueue是線程不安全的,PriorityBlockingQueue是線程安全的,本文主要介紹PriorityQueue。

【PriorityQueue】使用的注意事項:

  • 必須導入PeioriryQueue的包;
  • 放置的元素必須是能夠比較大小的,否則會拋出ClassCastException異常;
  • 不能放置null元素,否則會拋出NullPointerException;
  • 可以插入任意多的元素,內部會自動擴容;
  • 底層使用了堆數(shù)據(jù)結構,默認是小堆。如果要構建大堆,則需要提供比較器。

PriorityQueue的擴容方式:

  • 如果容量小于64時,是按照oldCapacity的2倍方式擴容的
  • 如果容量大于等于64,是按照oldCapacity的1.5倍方式擴容的
  • 如果容量超過MAX_ARRAY_SIZE,按照MAX_ARRAY_SIZE來進行擴容

int newCapacity = oldCapacity + ((oldCapacity < 64) ?

                      (oldCapacity + 2) : 

                   (oldCapacity >> 1));

PriorityQueue采用了:Comparble和Comparator兩種方式。

1. Comparble是默認的內部比較方式,如果用戶插入自定義類型對象時,該類對象必須要實現(xiàn)Comparble接口,并覆寫compareTo方法

2. 用戶也可以選擇使用比較器對象,如果用戶插入自定義類型對象時,必須要提供一個比較器類,讓該類實現(xiàn)Comparator接口并覆寫compare方法

// 用戶自己定義的比較器:直接實現(xiàn)Comparator接口,然后重寫該接口中的compare方法即可
class IntCmp implements Comparator<Integer>{
   @Override
   public int compare(Integer o1, Integer o2) {
      return o2-o1;
   }
}
PriorityQueue<Integer> p = new PriorityQueue<>(new IntCmp());

2、優(yōu)先級隊列的構造

構造器功能介紹
PriorityQueue()創(chuàng)建一個空的優(yōu)先級隊列,默認容量是11
PriorityQueue(int
initialCapacity)
創(chuàng)建一個初始容量為initialCapacity的優(yōu)先級隊列,注意:
initialCapacity不能小于1,否則會拋IllegalArgumentException異
PriorityQueue(Collection<?
extends E> c)
用一個集合來創(chuàng)建優(yōu)先級隊列

到此這篇關于Java 超詳細講解數(shù)據(jù)結構中的堆的應用的文章就介紹到這了,更多相關Java 堆的應用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 解讀java?try?catch?異常后還會繼續(xù)執(zhí)行嗎

    解讀java?try?catch?異常后還會繼續(xù)執(zhí)行嗎

    這篇文章主要介紹了解讀java?try?catch?異常后還會不會繼續(xù)執(zhí)行問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • SpringBoot自定義轉換器用法詳解

    SpringBoot自定義轉換器用法詳解

    在SpringBoot中,轉換器用于將一個類型的值轉換為另一個類型,這在處理HTTP請求參數(shù)、響應結果、表單數(shù)據(jù)等方面非常有用,SpringBoot提供了多種方式來定義和使用轉換器,本文給大家介紹了
    如何使用SpringBoot自定義轉換器,需要的朋友可以參考下
    2023-08-08
  • 詳解SpringBoot中RestTemplate的幾種實現(xiàn)

    詳解SpringBoot中RestTemplate的幾種實現(xiàn)

    這篇文章主要介紹了詳解SpringBoot中RestTemplate的幾種實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11
  • Java的wait(), notify()和notifyAll()使用心得

    Java的wait(), notify()和notifyAll()使用心得

    本篇文章是對java的 wait(),notify(),notifyAll()進行了詳細的分析介紹,需要的朋友參考下
    2013-08-08
  • SpringMVC攔截器詳解

    SpringMVC攔截器詳解

    本篇文章主要介紹了SpringMVC攔截器配置及使用方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-07-07
  • java導出包含多個sheet的Excel代碼示例

    java導出包含多個sheet的Excel代碼示例

    這篇文章主要介紹了java導出包含多個sheet的Excel,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • 一文掌握Xposed和LSPosed框架

    一文掌握Xposed和LSPosed框架

    Xposed和LSPosed都是用于Android系統(tǒng)的模塊化框架,允許用戶通過加載模塊來修改應用程序或系統(tǒng)行為,LSPosed是基于Xposed的現(xiàn)代化實現(xiàn),感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • Java基礎教程之整數(shù)運算

    Java基礎教程之整數(shù)運算

    Java的整數(shù)運算與C語言相同,遵循四則運算規(guī)則,下面這篇文章主要給大家介紹了關于Java基礎教程之整數(shù)運算的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-03-03
  • 下載遠程maven倉庫的jar?手動放到本地倉庫詳細操作

    下載遠程maven倉庫的jar?手動放到本地倉庫詳細操作

    這篇文章主要介紹了如何下載遠程maven倉庫的jar?手動放到本地倉庫,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 使用JPA插入枚舉類型字段

    使用JPA插入枚舉類型字段

    這篇文章主要介紹了使用JPA插入枚舉類型字段,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評論

开鲁县| 宜川县| 镇宁| 新和县| 麻城市| 镇平县| 磐石市| 雅安市| 长葛市| 仙游县| 凤凰县| 新密市| 突泉县| 临夏市| 普格县| 筠连县| 武穴市| 安塞县| 沾益县| 长泰县| 郯城县| 西充县| 龙海市| 伊金霍洛旗| 思茅市| 裕民县| 陆川县| 公主岭市| 于都县| 工布江达县| 昌平区| 兴隆县| 惠东县| 静海县| 集安市| 保德县| 六安市| 阿瓦提县| 衡阳市| 定安县| 安龙县|