国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆)

這篇具有很好參考價值的文章主要介紹了數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概念

優(yōu)先級隊列是啥??

隊列是一種先進先出 (FIFO) 的數(shù)據(jù)結(jié)構(gòu) ,但有些情況下, 操作的數(shù)據(jù)可能帶有優(yōu)先級,一般出隊
列時,可能需要優(yōu)先級高的元素先出隊列。
在這種情況下, 數(shù)據(jù)結(jié)構(gòu)應(yīng)該提供兩個最基本的操作,一個是返回最高優(yōu)先級對象,一個是添加新的對象 。這種數(shù)據(jù)結(jié)構(gòu)就是優(yōu)先級隊列 (Priority Queue) 。

堆是啥?

優(yōu)先級隊列的底層運用到堆這種數(shù)據(jù)結(jié)構(gòu)

堆的特點:總是一棵完全二叉樹

大根堆:

每一棵樹的根結(jié)點總是比左右子節(jié)點大

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

小根堆:

每一棵樹的根結(jié)點的值總是比左右子節(jié)點小,不考慮左右子節(jié)點誰大誰小

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

堆的存儲

存儲方式采用層序遍歷的方式把二叉樹的元素一一放到數(shù)組里面

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

那數(shù)組可不可以存儲非完全二叉樹呢?答案是可以的,但是會有空間浪費的情況

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

像上面右邊圖,4的位置沒有存儲元素,這就是一種空間浪費

來手搓一個堆

回顧一下二叉樹里面性質(zhì)的第五點

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

如何將普通數(shù)組轉(zhuǎn)換成堆?

把下面數(shù)組的元素畫成堆

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

先畫成一棵普通的二叉樹

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

畫成大根堆

28<37,互換。最左邊子樹49>25>18,把49變成該樹的根結(jié)點,最右邊的樹65>34>19,也進行交換

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

調(diào)整第二層的樹,49>15>37,49作為根,而15<18<25,下方的樹得把25變成根

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

最上面一層的樹,65>49>27,65做根結(jié)點,而27<34,所以34還得作為該子樹的根結(jié)點

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法這就是一個大根堆了

總結(jié):

1.從最后一棵子樹開始調(diào)整

2.在要變換的樹里面,從左右孩子里面找到最大的與根結(jié)點比較,大了就進行互換

3.如果能夠知道子樹根結(jié)點下標(biāo),那么下一棵子樹就是當(dāng)前根結(jié)點下標(biāo)-1

4.一直調(diào)整到0下標(biāo)這個樹為止

先寫個初步的代碼

public class TestHeap {
    private int[] elem;

    public int usedSize;//記錄當(dāng)前堆當(dāng)中有效的數(shù)據(jù)個數(shù)

    public TestHeap(){
        this.elem = new int[10];
    }

    //存儲數(shù)組
    public void initElem(int[] array){
        for (int i = 0; i < array.length; i++) {
            elem[i] = array[i];
            usedSize++;
        }
    }

問題

1.最后一棵子樹根結(jié)點下標(biāo)是多少

因為i = len-1,所以根結(jié)點index = (i-1)/2

    public void createHeap(){
        //usedSize-1相當(dāng)于最后一棵樹孩子結(jié)點的下標(biāo)i,再-1是為了求父結(jié)點
        for (int parent = (usedSize-1-1)/2; parent >= 0; parent--) {
            siftDown(parent,usedSize);
        }
    }

2.每棵子樹調(diào)整完之后,結(jié)束的位置怎么定?也就是我要從哪里開始調(diào)整下一棵子樹??

我們采用向下調(diào)整的方法(注意,雖然我們是從最后一顆樹往根結(jié)點方向調(diào)整,但是每一棵樹的處理我們還是采用從父結(jié)點到子節(jié)點的調(diào)整方法。為什么用不向上調(diào)整?后面我會說到。)

找到最后一個元素置為c,其根結(jié)點為p

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

調(diào)整完后不知道下面還有沒有元素要調(diào)整,所以c還得往下走?

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

此時c的坐標(biāo)是19 > 10了,所以可以停止了

    private void siftDown(int parent, int len){
        int child = 2 * parent + 1;
        while(child < len){
            //左右孩子比較大小
            if(elem[child] < elem[child + 1]){
                child = child + 1;
            }
            //走完上面的if,證明child下標(biāo)一定是左右兩個孩子最大值的下標(biāo)

        }
    }

現(xiàn)在問題來了,寫到這里會發(fā)生數(shù)組越界,如果我的child移到9下標(biāo)這里,那這個if判斷elem[child] < elem[child+1] 這里的child+1 = 10 = usedSize,而這棵樹根本就沒有10這個下標(biāo),造成了越界?

修改一下代碼

            if(child+1<len && elem[child] < elem[child + 1]){
                child = child + 1;
            }

后面就是比較孩子和父結(jié)點的代碼了

   /**
     * 向下調(diào)整
     * @param parent
     * @param len
     */
    private void siftDown(int parent, int len){
        int child = 2 * parent + 1;
        while(child < len){
            //左右孩子比較大小
            if(child+1<len && elem[child] < elem[child + 1]){
                child = child + 1;
            }
            //走完上面的if,證明child下標(biāo)一定是左右兩個孩子最大值的下標(biāo)
            if(elem[child] > elem[parent]){
                int tmp = elem[child];
                elem[child] = elem[parent];
                elem[parent] = tmp;
                parent = child;
                child = 2 * parent + 1;
            }else{
                break;//不用比不用調(diào)了
            }
        }
    }

測試一下,沒有問題??

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

怎么計算這個堆的時間復(fù)雜度?

考慮最壞情況,就是滿二叉樹的情況

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

首先明確一點,最后一層結(jié)點時不進行調(diào)整的,一般是從倒數(shù)第二層結(jié)點開始調(diào)整的

設(shè)樹的高度是h

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

T(N) = (h-1)*2^0+(h-2)*2^1+(h-3)*2^2+......+2*2^(h-3)+1*2^(h-2)

怎么求這個等式?采用錯位相減

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

根據(jù)等比求和公式

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

T(n) = 2 ^ h - 1 - h

因為n=2^h-1? ? --> h = log(n+1)

代進去T(n) = n - log(n+1)

因為log(n+1)的圖長這樣,n越大越趨于一個常數(shù)

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

所以整個等式占支配地位的還得是n,所以T(N) ≈ n? -->時間復(fù)雜度:O(N)


堆的插入

如果插入的數(shù)值比較小

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

如果插入的數(shù)值比較大,那就得一層一層進行調(diào)整

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

這種調(diào)整叫做向上調(diào)整

    public void swap(int i, int j){
        int tmp = elem[i];
        elem[i] = elem[j];
        elem[j] = tmp;
    }
    public void push(int val){
        if(isFull()){
            elem = Arrays.copyOf(elem, 2*elem.length);
        }
        elem[usedSize] = val;
        //向上調(diào)整
        siftUp(usedSize);
        usedSize++;
    }
    //判斷滿不滿
    public boolean isFull(){
        return usedSize == elem.length;
    }
    public void siftUp(int child){
        int parent = (child - 1) / 2;
        while(child>0){
            if(elem[child] > elem[parent]){
                swap(child,parent);
                child = parent;
                parent = (child - 1) / 2;
            }else{
                break;
            }
        }
    }

在測試?yán)锩姘?0push進去,沒有問題??

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

堆的插入的時間復(fù)雜度

因為最壞情況插入的元素是最大的,那這個元素最多也就向上調(diào)整到根節(jié)點的位置,也就是h

復(fù)雜度就是O(logN)?

欸那為什么不用向上調(diào)整來建堆呢???

我們分析一下,拿這棵滿二叉樹來說,最底層有8個元素,已經(jīng)占了一半了,網(wǎng)上建堆得每個元素都遍歷一遍,時間復(fù)雜度太大了

?數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

?數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

堆的刪除

因為堆的刪除一定是刪除優(yōu)先級最高的值,所以一定是刪除大根堆的根結(jié)點

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法比如這個,我們要做的就是刪除65

第一步:把65(0下標(biāo))與28(最后一個元素)進行交換

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

第二步:向下調(diào)整0下標(biāo)

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

    public int pop(){
        if(empty()){
            throw new EmptyException("數(shù)組空了!");
        }
        int oldVal = elem[0];
        swap(0,usedSize-1);
        usedSize--;
        siftDown(0,usedSize);
        return oldVal;
    }

    public boolean empty(){
        return usedSize == 0;
    }

測試一下,沒有問題??

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

習(xí)題:

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

選A(可以自己畫圖,反正就是層序遍歷畫樹)

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

選C

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法?數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

總共比較3次,左邊那個15的原本就是小根堆,所以就不用比較

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法
選C

PriorityQueue

Java集合框架提供了PriorityQueue的優(yōu)先級隊列

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

注意事項:

        PriorityQueue<Student> priorityQueue1 = new PriorityQueue<>();
        priorityQueue1.offer(new Student("zhangsan",10));
        priorityQueue1.offer(new Student("lisi",12));

?1.PriorityQueue放入的元素必須能比較大小,否則會報出下面的錯誤?

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

2.不能插入null對象,否則會報出下面的錯誤

        PriorityQueue<Student> priorityQueue1 = new PriorityQueue<>();
        priorityQueue1.offer(null);

?數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

3.沒有容量限制,可以插入任意多個元素,內(nèi)部會自動擴容

4.插入和刪除都是O(logn)?

5.使用了最小堆的數(shù)據(jù)結(jié)構(gòu),所以每次獲取的元素都是最小的元素

oj練習(xí)

面試題 17.14. 最小K個數(shù) - 力扣(LeetCode)

設(shè)計一個算法,找出數(shù)組中最小的k個數(shù)。以任意順序返回這k個數(shù)均可。

示例:

輸入: arr = [1,3,5,7,2,4,6,8], k = 4
輸出: [1,2,3,4]

提示:

  • 0 <= len(arr) <= 100000
  • 0 <= k <= min(100000, len(arr))

方法一:

建立最小堆,把堆頂k個元素輸出出來就行了

代碼

    public int[] smallestK(int[] arr, int k) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();

        //向上調(diào)整 O(logN)
        for (int i = 0; i < array.length; i++) {
            priorityQueue.offer(array[i]);
        }
        int[] ret = new int[k];
        //k*logN
        for (int i = 0; i < k; i++) {
            ret[i] = priorityQueue.poll();
        }
        return ret;
    }

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

雖然通過了,但是時間復(fù)雜度有點大?

方法二:

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

1.建立大根堆,大小為k,比如我們可以拿前三個元素來建一個大根堆

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

2.從第k+1個元素開始比較,如果比堆頂元素小,則入堆。當(dāng)前的堆頂元素(較大的)就舍棄掉,因為已經(jīng)不符合我對前k個最小的元素的要求了

遍歷完整個大根堆長這樣

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

問題來了,PriorityQueue是默認(rèn)采用小根堆的底層,那我們要怎么讓它采用大根堆呢

PriorityQueue源碼里面的有一個compare函數(shù)

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

這個函數(shù)外層是compareTo函數(shù)

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

這兩個函數(shù)結(jié)合一下,把小的放在前面,大的放在后面,所以實現(xiàn)了小根堆的底層

我們可以重寫PriorityQueue里面的compare函數(shù),把大的放在前面

class Imp implements Comparator<Integer>{
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2.compareTo(o1);
    }
}

整個的代碼(上面的重寫可以扔到匿名內(nèi)部類里面)

    public static int[] smallestK(int[] array, int k) {
        int[] ret = new int[k];
        if(array == null || k <= 0) {
            return ret;
        }
        //匿名內(nèi)部類
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2.compareTo(o1);
            }
        });

        //1、建立大小為k的大根堆 O(K*logK)
        for (int i = 0; i < k; i++) {
            priorityQueue.offer(array[i]);
        }

        //2、遍歷剩下的元素 (N-K)*logK
        // (K*logK) + N*logK  - K*logK   =   N*logK  -->時間復(fù)雜度
        for (int i = k; i < array.length; i++) {
            int top = priorityQueue.peek();//27
            if(array[i] < top) {
                priorityQueue.poll();
                priorityQueue.offer(array[i]);
            }
        }
        //下面這個不能算topK的復(fù)雜度 這個地方是整理數(shù)據(jù)
        //k*logK
        for (int i = 0; i < k; i++) {
            ret[i] = priorityQueue.poll();
        }
        return ret;
    }

?數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

別看力扣上面的通過時間,我們要自行分析時間復(fù)雜度?

拓展:Comparable接口和Comparator接口

使用Comparable意味著這個類只能有一種比較規(guī)則(你拿你自己和別人家的孩子比成績)

一個類只能實現(xiàn)一次Comparable,這種寫法對類的侵入性比較強

使用Comparator意味著可以有多重比較規(guī)則(你媽拿你和別人家孩子對比的時候,可以比較學(xué)習(xí)成績,聽話程度,做不做家務(wù))

這里的compareTo和compare方法就是回調(diào)函數(shù)

回調(diào)函數(shù)是一種特殊的函數(shù),它作為參數(shù)傳遞給另一個函數(shù),并在被調(diào)用函數(shù)執(zhí)行完畢后被調(diào)用


堆排序

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

把這個數(shù)組從小到大排序,需要建立大根堆

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

再把這棵樹放到堆底,這樣最大的元素就有序了

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

再按照大根堆進行排序(已經(jīng)有序的元素就不管了),把最大元素49放到堆頂,然后再和堆第的15交換

數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆),Java數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)結(jié)構(gòu),1024程序員節(jié),java,算法

以此類推,設(shè)置一個堆底end,每次拿0下標(biāo)的元素和它交換,交換完end--

    public void heapSort(){
        int end = usedSize-1;
        while(end>0){
            swap(0,end);
            siftDown(0,end);
            end--;
        }
    }

時間復(fù)雜度O(N*logN)文章來源地址http://www.zghlxwxcb.cn/news/detail-714669.html

到了這里,關(guān)于數(shù)據(jù)結(jié)構(gòu):優(yōu)先級隊列(堆)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu)與算法-優(yōu)先級隊列

    Gitee上開源的數(shù)據(jù)結(jié)構(gòu)與算法代碼庫:數(shù)據(jù)結(jié)構(gòu)與算法Gitee代碼庫 優(yōu)先級隊列,按照優(yōu)先級別依次輸出 計算機科學(xué)中,堆是一種基于樹的數(shù)據(jù)結(jié)構(gòu),通常用 完全二叉樹 實現(xiàn)。堆的特性如下 在大頂堆中,任意節(jié)點 C 與它的父節(jié)點 P 符合 P . v a l u e ≥ C . v a l u e P.value geq C.val

    2024年02月13日
    瀏覽(36)
  • 數(shù)據(jù)結(jié)構(gòu) 之 優(yōu)先級隊列(堆) (PriorityQueue)

    數(shù)據(jù)結(jié)構(gòu) 之 優(yōu)先級隊列(堆) (PriorityQueue)

    ??歡迎大家觀看AUGENSTERN_dc的文章(o゜▽゜)o☆?? ??感謝各位讀者在百忙之中抽出時間來垂閱我的文章,我會盡我所能向的大家分享我的知識和經(jīng)驗?? ??希望我們在一篇篇的文章中能夠共同進步!?。???個人主頁:AUGENSTERN_dc ??個人專欄:C語言?|?Java | 數(shù)據(jù)結(jié)構(gòu) ?個人

    2024年03月20日
    瀏覽(27)
  • 數(shù)據(jù)結(jié)構(gòu)之優(yōu)先級隊列【堆】(Heap)

    數(shù)據(jù)結(jié)構(gòu)之優(yōu)先級隊列【堆】(Heap)

    目錄 1. 優(yōu)先級隊列(Priority Queue) 2.堆的概念 3.堆的存儲方式 4.堆的創(chuàng)建 5.用堆模擬實現(xiàn)優(yōu)先級隊列 ?6.PriorityQueue常用接口介紹 6.1?PriorityQueue的特點 6.2?PriorityQueue幾種常見的構(gòu)造方式 7.top-k問題 8.堆排序 本篇主要內(nèi)容總結(jié) (1)優(yōu)先級隊列底層是堆來實現(xiàn)的 (2)堆的本質(zhì)是

    2024年02月01日
    瀏覽(51)
  • 【一起學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法】優(yōu)先級隊列(堆)

    【一起學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法】優(yōu)先級隊列(堆)

    如果我們給每個元素都分配一個數(shù)字來標(biāo)記其優(yōu)先級,不妨設(shè)較小的數(shù)字具有較高的優(yōu)先級,這樣我們就可以在一個集合中訪問優(yōu)先級最高的元素并對其進行查找和刪除操作了。這樣,我們就引入了 優(yōu)先級隊列 這種數(shù)據(jù)結(jié)構(gòu)。 優(yōu)先級隊列(priority queue) 是0個或多個元素的集

    2024年01月19日
    瀏覽(24)
  • 數(shù)據(jù)結(jié)構(gòu) - 6(優(yōu)先級隊列(堆)13000字詳解)

    數(shù)據(jù)結(jié)構(gòu) - 6(優(yōu)先級隊列(堆)13000字詳解)

    堆分為兩種:大堆和小堆。它們之間的區(qū)別在于元素在堆中的排列順序和訪問方式。 大堆(Max Heap): 在大堆中,父節(jié)點的值比它的子節(jié)點的值要大。也就是說,堆的根節(jié)點是堆中最大的元素。大堆被用于實現(xiàn)優(yōu)先級隊列,其中根節(jié)點的元素始終是隊列中最大的元素。 大堆

    2024年02月08日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu)】 優(yōu)先級隊列(堆)與堆的建立

    【數(shù)據(jù)結(jié)構(gòu)】 優(yōu)先級隊列(堆)與堆的建立

    前面介紹過隊列, 隊列是一種先進先出(FIFO)的數(shù)據(jù)結(jié)構(gòu) ,但有些情況下,操作的數(shù)據(jù)可能帶有優(yōu)先級,一般出隊列時,可能需要優(yōu)先級高的元素先出隊列,該中場景下,使用隊列顯然不合適。 比如:在手機上玩游戲的時候,如果有來電,那么系統(tǒng)應(yīng)該優(yōu)先處理打進來的電話

    2024年02月10日
    瀏覽(18)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】03 隊列(順序隊列--循環(huán)隊列--優(yōu)先級隊列--鏈隊列)

    【數(shù)據(jù)結(jié)構(gòu)與算法】03 隊列(順序隊列--循環(huán)隊列--優(yōu)先級隊列--鏈隊列)

    隊列( queue )是一種常見的數(shù)據(jù)結(jié)構(gòu),它遵循先進先出(FIFO)的原則。隊列可以理解為一個具有兩個端點的線性數(shù)據(jù)結(jié)構(gòu),其中一個端點稱為\\\"隊尾\\\"(rear),用于插入新元素,另一個端點稱為\\\"隊首\\\"(front),用于移除元素。新元素被插入到隊尾,而最早插入的元素總是在隊

    2024年02月08日
    瀏覽(21)
  • 【數(shù)據(jù)結(jié)構(gòu)初階】——第八節(jié).優(yōu)先級隊列(小根堆的模擬實現(xiàn))

    【數(shù)據(jù)結(jié)構(gòu)初階】——第八節(jié).優(yōu)先級隊列(小根堆的模擬實現(xiàn))

    ?作者簡介:大家好,我是未央; 博客首頁: 未央.303 系列專欄:Java初階數(shù)據(jù)結(jié)構(gòu) 每日一句:人的一生,可以有所作為的時機只有一次,那就是現(xiàn)在?。?! 目錄 文章目錄 前言 引言 一、堆的概念 二、堆的性質(zhì)? 三、堆的操作 3.1 向下調(diào)整算法 3.2?小根堆的創(chuàng)建 3.3?向上調(diào)整

    2024年02月07日
    瀏覽(31)
  • 經(jīng)典TopK問題、優(yōu)先級隊列 與 堆的糾葛一文為你解惑——數(shù)據(jù)結(jié)構(gòu)

    經(jīng)典TopK問題、優(yōu)先級隊列 與 堆的糾葛一文為你解惑——數(shù)據(jù)結(jié)構(gòu)

    前言: 本篇文章以 TopK 問題為引,具體闡述了 PriorityQueue 實現(xiàn)的基本邏輯——堆 數(shù)據(jù)結(jié)構(gòu),以及PriorityQueue 的常用方法。如有問題歡迎看官朋友指正,如果覺得文章還不錯的話,求點贊、收藏、評論 三連。 重點: 堆的基本實現(xiàn)邏輯 PriorityQueue 運用和源碼分析 TopK 問題的解法

    2023年04月22日
    瀏覽(18)
  • Java優(yōu)先級隊列-堆

    大家好,我是曉星航。今天為大家?guī)淼氖?Java優(yōu)先級隊列(堆) 的講解!?? 使用數(shù)組保存二叉樹結(jié)構(gòu),方式即將二叉樹用 層序遍歷 方式放入數(shù)組中。 一般只適合表示完全二叉樹,因為非完全二叉樹會有空間的浪費。 這種方式的主要用法就是堆的表示。 已知雙親(parent)的下

    2023年04月16日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包