欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?超詳細(xì)講解數(shù)據(jù)結(jié)構(gòu)中的堆的應(yīng)用

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

一、堆的創(chuàng)建

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

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

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

  • parent右孩子是否存在,存在找到左右孩子中最小的孩子,讓child進(jìn)行標(biāo)記
  • 將parent與較小的孩子child比較,如果:

parent小于較小的孩子child,調(diào)整結(jié)束否則:交換parent與較小的孩子child,交換完成之后,parent中大的元素向下移動,可能導(dǎo)致子樹不滿足堆的性質(zhì),因此需要繼續(xù)向下調(diào)整,即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)建堆

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

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

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

 二、堆的插入和刪除

1、堆的插入

  • 將要插入的元素放在堆的最后,如果放不了,進(jìn)行擴(kuò)容
  • 將新插入的節(jié)點(diǎn)向上調(diào)整,直到滿足堆的性質(zhì)

 【向上調(diào)整】

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ù)堆的性質(zhì),對刪除的一定是堆頂元素。步驟如下:

  • 將堆頂元素和最后一個(gè)元素交換
  • 堆的元素個(gè)數(shù)減一
  • 對堆頂元素進(jìn)行向下調(diào)整

 三、堆的應(yīng)用

1、堆排序

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

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

交換堆頂元素和堆得最后一個(gè)元素,進(jìn)行向下調(diào)整,直到堆有序。

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

top-k問題:求數(shù)據(jù)集合中前k個(gè)大或者小的元素,一般數(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)先級隊(duì)列。PriorityQueue是線程不安全的,PriorityBlockingQueue是線程安全的,本文主要介紹PriorityQueue。

【PriorityQueue】使用的注意事項(xiàng):

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

PriorityQueue的擴(kuò)容方式:

  • 如果容量小于64時(shí),是按照oldCapacity的2倍方式擴(kuò)容的
  • 如果容量大于等于64,是按照oldCapacity的1.5倍方式擴(kuò)容的
  • 如果容量超過MAX_ARRAY_SIZE,按照MAX_ARRAY_SIZE來進(jìn)行擴(kuò)容

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

                      (oldCapacity + 2) : 

                   (oldCapacity >> 1));

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

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

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

// 用戶自己定義的比較器:直接實(shí)現(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)先級隊(duì)列的構(gòu)造

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

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

相關(guān)文章

  • 在spring boot中使用java線程池ExecutorService的講解

    在spring boot中使用java線程池ExecutorService的講解

    今天小編就為大家分享一篇關(guān)于在spring boot中使用java線程池ExecutorService的講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java數(shù)據(jù)結(jié)構(gòu)之循環(huán)隊(duì)列簡單定義與用法示例

    Java數(shù)據(jù)結(jié)構(gòu)之循環(huán)隊(duì)列簡單定義與用法示例

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之循環(huán)隊(duì)列簡單定義與用法,簡要描述了循環(huán)隊(duì)列的概念、原理,并結(jié)合實(shí)例形式分析了java循環(huán)隊(duì)列的定義與使用方法,需要的朋友可以參考下
    2017-10-10
  • Java實(shí)現(xiàn)的動態(tài)數(shù)字時(shí)鐘功能示例【顯示世界時(shí)間】

    Java實(shí)現(xiàn)的動態(tài)數(shù)字時(shí)鐘功能示例【顯示世界時(shí)間】

    這篇文章主要介紹了Java實(shí)現(xiàn)的動態(tài)數(shù)字時(shí)鐘功能,結(jié)合實(shí)例形式分析了java顯示北京、紐約、倫敦等世界時(shí)間的相關(guān)日期時(shí)間運(yùn)算操作技巧,需要的朋友可以參考下
    2019-03-03
  • 掌握SpringMVC中@InitBinder的實(shí)際應(yīng)用

    掌握SpringMVC中@InitBinder的實(shí)際應(yīng)用

    這篇文章主要介紹了掌握SpringMVC中@InitBinder的實(shí)際應(yīng)用,@InitBinder是Spring MVC框架中的一個(gè)注解,用于自定義數(shù)據(jù)綁定的方法,通過在控制器中使用@InitBinder注解,可以將特定的數(shù)據(jù)綁定邏輯應(yīng)用于請求參數(shù)的處理過程中,需要的朋友可以參考下
    2023-10-10
  • MyBatis分頁查詢與特殊字符處理方式

    MyBatis分頁查詢與特殊字符處理方式

    這篇文章主要介紹了MyBatis分頁查詢與特殊字符處理方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • HttpClient實(shí)現(xiàn)遠(yuǎn)程調(diào)用

    HttpClient實(shí)現(xiàn)遠(yuǎn)程調(diào)用

    這篇文章主要為大家詳細(xì)介紹了HttpClient實(shí)現(xiàn)遠(yuǎn)程調(diào)用的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Java ScheduledExecutorService定時(shí)任務(wù)案例講解

    Java ScheduledExecutorService定時(shí)任務(wù)案例講解

    這篇文章主要介紹了Java ScheduledExecutorService定時(shí)任務(wù)案例講解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 實(shí)例詳解SpringMVC入門使用

    實(shí)例詳解SpringMVC入門使用

    大家好,本篇文章主要講的是實(shí)例詳解SpringMVC入門使用,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • springboot整合skywalking的使用詳解

    springboot整合skywalking的使用詳解

    隨著分布式應(yīng)用大規(guī)模部署,應(yīng)用可觀測性從理論到落地已經(jīng)在眾多大型互聯(lián)網(wǎng)應(yīng)用中得到實(shí)踐,比如針對日志可視化ELK解決方案,分布式鏈路追蹤APM解決方案SkyWalking等,今天將詳細(xì)介紹下APM解決方案中一款重要工具SkyWalking的使用,需要的朋友可以參考下
    2024-01-01
  • SpringBoot集成Spring Security用JWT令牌實(shí)現(xiàn)登錄和鑒權(quán)的方法

    SpringBoot集成Spring Security用JWT令牌實(shí)現(xiàn)登錄和鑒權(quán)的方法

    這篇文章主要介紹了SpringBoot集成Spring Security用JWT令牌實(shí)現(xiàn)登錄和鑒權(quán)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05

最新評論