激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - JAVA十大排序算法之堆排序詳解

JAVA十大排序算法之堆排序詳解

2021-11-30 11:05阿粵Ayue Java教程

這篇文章主要介紹了java中的冒泡排序,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考

 

堆排序

這里的堆并不是JVM中堆棧的堆,而是一種特殊的二叉樹,通常也叫作二叉堆。它具有以下特點:

  • 它是完全二叉樹
  • 堆中某個結點的值總是不大于或不小于其父結點的值

 

知識補充

 

二叉樹

樹中節(jié)點的子節(jié)點不超過2的有序樹

JAVA十大排序算法之堆排序詳解

 

滿二叉樹

二叉樹中除了葉子節(jié)點,每個節(jié)點的子節(jié)點都為2,則此二叉樹為滿二叉樹。

JAVA十大排序算法之堆排序詳解

 

完全二叉樹

如果對滿二叉樹的結點進行編號,約定編號從根結點起,自上而下,自左而右。則深度為k的,有n個結點的二叉樹,當且僅當其每一個結點都與深度為k的滿二叉樹中編號從1至n的結點一一對應時,稱之為完全二叉樹。

特點:葉子結點只能出現(xiàn)在最下層和次下層,且最下層的葉子結點集中在樹的左部。需要注意的是,滿二叉樹肯定是完全二叉樹,而完全二叉樹不一定是滿二叉樹。

JAVA十大排序算法之堆排序詳解

 

二叉堆

二叉堆是一種特殊的堆,可以被看做一棵完全二叉樹的數(shù)組對象,而根據(jù)其性質又可以分為下面兩種:

  • 大根堆:每一個根節(jié)點都大于等于它的左右孩子節(jié)點,也叫最大堆
  • 小根堆:每一個根節(jié)點都小于等于它的左右孩子節(jié)點,也叫最小堆

如果把一個數(shù)組通過大根堆的方式來表示(數(shù)組元素的值是可變的),如下:

JAVA十大排序算法之堆排序詳解

由此可以推出:

  • 對于位置為 k 的節(jié)點,其子節(jié)點的位置分別為,左子節(jié)點 = 2k + 1,右子節(jié)點 = 2(k + 1)

如:對于 k = 1,其節(jié)點的對應數(shù)組為 5

左子節(jié)點的位置為 3,對應數(shù)組的值為 3

右子節(jié)點的位置為 4,對應數(shù)組的值為 2

  • 最后一個非葉子節(jié)點的位置為 (n/2) - 1,n為數(shù)組長度

如:數(shù)組長度為6,則 (6/2) - 1 = 2,即位置 2 為最后一個非葉子節(jié)點

給定一個隨機數(shù)組[35,63,48,9,86,24,53,11],將該數(shù)組視為一個完全二叉樹:

JAVA十大排序算法之堆排序詳解

從上圖很明顯的可以看出,這個二叉樹不符合大根堆的定義,但是可以通過調整,使它變?yōu)樽畲蠖选H绻?strong>從最后一個非葉子節(jié)點開始,從下到上,從右往左調整,則:

JAVA十大排序算法之堆排序詳解

通過上面的調整,該二叉樹為最大堆,這個時候開始排序,排序規(guī)則:

  • 將堆頂元素和尾元素交換交換
  • 后重新調整元素的位置,使之重新變成二叉堆

JAVA十大排序算法之堆排序詳解

 

代碼實現(xiàn)

public class HeapSort {
    public static final int[] ARRAY = {35, 63, 48, 9, 86, 24, 53, 11};
    public static int[] sort(int[] array) {
        //數(shù)組的長度
        int length = array.length;
        if (length < 2) return array;
        //首先構建一個最大堆
        buildMaxHeap(array);
        //調整為最大堆之后,頂元素為最大元素并與微元素交換
        while (length > 0) {//當lenth <= 0時,說明已經(jīng)到堆頂
            //交換
            swap(array, 0, length - 1);
            length--;//交換之后相當于把樹中的最大值彈出去了,所以要--
            //交換之后從上往下調整使之成為最大堆
            adjustHeap(array, 0, length);
        }
        return array;
    }
    //對元素組構建為一個對應數(shù)組的最大堆
    private static void buildMaxHeap(int[] array) {
        //在之前的分析可知,最大堆的構建是從最后一個非葉子節(jié)點開始,從下往上,從右往左調整
        //最后一個非葉子節(jié)點的位置為:array.length/2 - 1
        for (int i = array.length / 2 - 1; i >= 0; i--) {
            //調整使之成為最大堆
            adjustHeap(array, i, array.length);
        }
    }
    /**
     * 調整
     * @param parent 最后一個非葉子節(jié)點
     * @param length 數(shù)組的長度
     */
    private static void adjustHeap(int[] array, int parent, int length) {
        //定義最大值的索引
        int maxIndex = parent;
        //parent為對應元素的位置(數(shù)組的索引)
        int left = 2 * parent + 1;//左子節(jié)點對應元素的位置
        int right = 2 * (parent + 1);//右子節(jié)點對應元素的位置
        //判斷是否有子節(jié)點,再比較父節(jié)點和左右子節(jié)點的大小
        //因為parent最后一個非葉子節(jié)點,所以如果有左右子節(jié)點則節(jié)點的位置都小于數(shù)組的長度
        if (left < length && array[left] > array[maxIndex]) {//左子節(jié)點如果比父節(jié)點大
            maxIndex = left;
        }
        if (right < length && array[right] > array[maxIndex]) {//右子節(jié)點如果比父節(jié)點大
            maxIndex = right;
        }
        //maxIndex為父節(jié)點,若發(fā)生改變則說明不是最大節(jié)點,需要交換
        if (maxIndex != parent) {
            swap(array, maxIndex, parent);
            //交換之后遞歸再次調整比較
            adjustHeap(array, maxIndex, length);
        }
    }
    //交換
    private static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    public static void print(int[] array) {
        for (int i : array) {
            System.out.print(i + "  ");
        }
        System.out.println("");
    }
    public static void main(String[] args) {
        print(ARRAY);
        System.out.println("============================================");
        print(sort(ARRAY));
    }
}

 

時間復雜度

堆的時間復雜度是 O(nlogn)

參考:堆排序的時間復雜度分析

 

算法穩(wěn)定性

堆的結構為,對于位置為 k 的節(jié)點,其子節(jié)點的位置分別為,左子節(jié)點 = 2k + 1,右子節(jié)點 = 2(k + 1),最大堆要求父節(jié)點大于等于其2個子節(jié)點,最小堆要求父節(jié)點小于等于其2個子節(jié)點。

在一個長為n的序列,堆排序的過程是從第n/2開始和其子節(jié)點共3個值選擇最大(最大堆)或者最小(最大堆),這3個元素之間的選擇當然不會破壞穩(wěn)定性。但當為n/2-1,n/2-2,… 1 這些個父節(jié)點選擇元素時,就會破壞穩(wěn)定性。有可能第n/2個父節(jié)點交換把后面一個元素交換過去了,而第n/2-1個父節(jié)點把后面一個相同的元素沒有交換,那么這2個相同的元素之間的穩(wěn)定性就被破壞了。所以,堆排序不是穩(wěn)定的排序算法。

 

思考

對于快速排序來說,其平均復雜度為O(nlogn),堆排序也是O(nlogn),怎么選擇?如下題:

leetcode:數(shù)組中的第K個最大元素

此題的意思是對于一個無序數(shù)組,經(jīng)過排序后的第 k 個最大的元素。

我們知道快速排序是需要對整個數(shù)組進行排序,這樣才能取出第 k 個最大的元素。

如果使用堆排序,且是最大堆的方式,則第k次循環(huán)即可找出第 k 個最大的元素,并不需要吧整個數(shù)組排序。

所以對于怎么選擇的問題,要看具體的場景,或者是兩者都可。

 

總結

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關注服務器之家的更多內(nèi)容!

原文鏈接:https://blog.csdn.net/weixin_43477531/article/details/119821587

延伸 · 閱讀

精彩推薦
  • Java教程Java實現(xiàn)搶紅包功能

    Java實現(xiàn)搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現(xiàn)搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發(fā)項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩(wěn)中求8032021-07-12
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網(wǎng)2942020-09-17
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經(jīng)有好久沒有升過級了。升級完畢重啟之后,突然發(fā)現(xiàn)好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數(shù)據(jù)的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發(fā)現(xiàn)了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
主站蜘蛛池模板: 国产91对白叫床清晰播放 | 在线亚州| 亚洲成人久久精品 | 久久国产精品久久久久久电车 | 成人一级免费 | 国产一级毛片av | 高清在线观看av | 国产精品久久久久久久久久免 | 久久久久久久一区二区 | 国产毛片视频 | 久久久av影视 | 成人资源在线观看 | 欧美精品一区自拍a毛片在线视频 | 偷偷操偷偷操 | 1314成人网| 亚洲欧美国产高清 | 成人欧美日韩一区二区三区 | 久操福利视频 | 免费人成在线播放 | av在线免费观看不卡 | 国产午夜精品理论片a级探花 | 成人黄色小视频在线观看 | 国产精品成人一区二区三区电影毛片 | 一区二区三区四区国产 | 久草在线观看福利视频 | 欧美成人免费一级 | 91久久国产露脸精品免费 | 亚洲国产精品久久久久久久久久久 | av在线日韩 | 最新中文字幕日本 | 亚洲精品在线观看网站 | 日韩精品羞羞答答 | 欧美成人精品一区二区三区 | 欧美一页 | 国产chinesehd精品91 | 香蕉黄色网 | 亚洲精品在线观看网站 | 精品一区二区久久久久久久网精 | 一级黄色影院 | 毛片免费在线 | 欧美一级爱爱 |