堆排序

一、什么是堆排序

? ? ? ? 堆排序是將數(shù)組看做一個完全二叉樹(附錄里有二叉樹的解釋),具有以下的性質(zhì):

1)每個節(jié)點的值都大于子節(jié)點的值,叫做大頂堆。

大頂堆

2)每個節(jié)點的值都小于子節(jié)點的值,叫做小頂堆。

小頂堆

二、堆排序的實現(xiàn)原理

? ? ? ? 大頂堆是將數(shù)組按照升序的方式進行排序。原理是:

(1)從最后一個根節(jié)點開始,比較父節(jié)點和兩個子節(jié)點的值,如果子節(jié)點的值大于父節(jié)點,則交換兩點的數(shù)值,否則不交換。

(2)從最后一個根節(jié)點依次比較到頂點 ,也就是上圖0節(jié)點的位置。這樣進行一輪比較之后,得到的0節(jié)點的數(shù)值就是該數(shù)組中最大的數(shù)值。

(3)再將0節(jié)點的數(shù)值與該數(shù)組最后一個子節(jié)點的數(shù)值進行交換。這是最后一個子節(jié)點位置上的值便是該數(shù)組中最大的值。

(4)這時,把數(shù)組的倒數(shù)第二個子節(jié)點當做數(shù)組的結(jié)尾,再次將0節(jié)點作為父節(jié)點進行大頂堆操作,這樣重復到數(shù)組的結(jié)尾為1節(jié)點,數(shù)組排序完成。

(5)將數(shù)組輸出可以看到該數(shù)組變?yōu)橐粋€升序的數(shù)組。

? ? ? ? 小頂堆則與大頂堆正好相反。

三、代碼實現(xiàn):

package JavaDay_13

publc class Heapsort {

public static void main(String[] args) {?

?????????????int[] arr = {1,5,6,8,7,2,3,4,9,4,15,12}; //創(chuàng)建一個數(shù)組

? ? ? ? ? ? ?heapSort(arr); //調(diào)用heapSort方法進行第一次排序,選出最大值放在0節(jié)點

????????????for(int i=0;i<arr.length;i++){? ?//將arr數(shù)組輸出

? ? ? ? ? ? ? ? ? ? System.out.print(arr[i]+" ");

????????????}

}

public static void heapSort(int[]arr){

? ? ? ? ? ? ? int n= arr.length-1;

? ? ? ? ? ? ?for(int i=n/2-1;i>=0;i++){? ? ? ? ? ? //從最后一個根節(jié)點開始,直到0節(jié)點位置

? ? ? ? ? ? ? ? ?heapAdjust(arr,i,n);? ? ? ? ? ? ? ? // 傳入?yún)?shù)arr數(shù)組,父節(jié)點 i ,數(shù)組長度n

?????????????????????}?

? ? ? ? ? ? for(int i=n;i>0;i--) {? ? ? ? ? ? ? ? ? ? //從最后一個節(jié)點開始,到取到倒數(shù)第二個節(jié)點

?????????????????????swap(arr,i);? ? ? ? ? ? ? ? ? ? ? //調(diào)用方法,將此時的 i 與arr數(shù)組的第一個值交換

? ? ? ? ? ? ? ? ? ? ?heapAdjust(arr,0,i-1);? ? ? ? //再次構(gòu)建大頂堆

?????????????????????}

?}?

?????public static void heapAdjust(int[] arr,int parent,int length) {?

?????????????????????int temp = arr[parent];? ? ? ? ? ? ? ? ?//設置一個初始值記錄arr[parent]的數(shù)值

? ? ? ? ? ? ? ? for(int i=parent*2+1;i<=length;i=i*2+1) {?

?// i為父節(jié)點的左節(jié)點,每次循環(huán)結(jié)束后,i節(jié)點成為父節(jié)點,i迭代為自己之前的數(shù)的左節(jié)點

? ? ? ? ? ? ? ? ? ? ? ? ? if(i<length && arr[i]<arr[i+1]){

? ? ? ? ? ? ? ? ? ? ? ? ? ? ????????????? i++;? ? ? //如果i的左節(jié)點小于右節(jié)點,則i+1變?yōu)橛夜?jié)點

????????????????????????????????????}

?????????????????????????????????if(temp>arr[i])? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????????break;? ? // 如果左右節(jié)點中較大的值小于父節(jié)點,則跳出

? ? ? ? ? ????????????????????????? }

? ? ? ? ????????????? ????? arr[parent] = arr[i];? ?//讓父節(jié)點的值變?yōu)閕節(jié)點的值

? ? ? ? ? ? ? ? ? ? ? ? ? ?parent = i;? ? ? ? ? ? //此時父節(jié)點變?yōu)閕;

? ? ? ? ? ? ? ? ? ?}

? ? ? ? arr[parent] = temp;? ? ? ? ? ? //? 將剛剛得到的父節(jié)點賦值給新位置

? ? }

? ? public static void swap(int[] arr,int i) {? //將數(shù)組arr中的i的值與0交換

? ? ? ? ????????????int temp = arr[0];

? ? ? ? ????????????arr[0] = arr[i];

? ? ? ? ????????????arr[i] = temp;

????????? ? }

}

附錄:

????????在計算機科學中,二叉樹是每個結(jié)點最多有兩個子樹的樹結(jié)構(gòu)。通常子樹被稱作“左子樹”和“右子樹”。

????????完全二叉樹——若設二叉樹的高度為h,除第 h 層外,其它各層 (1~h-1) 的結(jié)點數(shù)都達到最大個數(shù),第 h 層有葉子結(jié)點,并且葉子結(jié)點都是從左到右依次排布,這就是完全二叉樹。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 堆是一棵滿足一定性質(zhì)的二叉樹,具體的講堆具有如下性質(zhì):父節(jié)點的鍵值總是不大于它的孩子節(jié)點的鍵值(小頂堆), 堆可以...
    9527Roy閱讀 745評論 0 0
  • 背景介紹:是指利用堆這種數(shù)據(jù)結(jié)構(gòu)所設計的一種排序算法。堆積是一個近似完全二叉樹的結(jié)構(gòu),并同時滿足堆積的性質(zhì):即子結(jié)...
    DreamFish閱讀 246評論 0 1
  • 姓名:王懷帥 學號:16040410035 轉(zhuǎn)載自:http://www.itdecent.cn/p/86428c...
    錯錯對閱讀 263評論 0 1
  • 天空的湛藍 在云的縫隙中掙扎 指尖妄圖撕裂 厚厚的云層 觸摸明亮的柔滑 暮色下 我在星上鐫刻你的身影 抹去天涯
    星風評車閱讀 198評論 0 1
  • 認識一個人五年了,她可以說參與了我有生之年的四分之一,甚至是懵懂青春的全部。然而,到此也算結(jié)束了。她的消失好比一...
    艾_5fbf閱讀 175評論 0 0

友情鏈接更多精彩內(nèi)容