摘要:轉自 http://www.cnblogs.com/MOBIN/p/5374217.html
作爲選擇排序的改進版,堆排序可以把每一趟元素的比較結果保存下來,以便我們在選擇最小/大元素時對已經比較過的元素做出相應的調整。 堆排序是一種樹形選擇排序,在排序過程中可以把元素看成是一顆完全二叉樹,每個節點都大(小)於它的兩個子節點,當每個節點都大於等於它的兩個子節點時,就稱爲大頂堆,也叫堆有序; 當每個節點都小於等於它的兩個子節點時,就稱爲小頂堆。
代碼實現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public class HeapSort { private static void heapSort( int [] arr) { int len = arr.length - 1 ; for ( int i = len/ 2 - 1 ; i >= 0 ; i --){ //堆構造 heapAdjust(arr,i,len); } while (len >= 0 ){ swap(arr, 0 ,len--); //將堆頂元素與尾節點交換後,長度減1,尾元素最大 heapAdjust(arr, 0 ,len); //再次對堆進行調整 } } public static void heapAdjust( int [] arr, int i, int len){ int left,right,j ; while ((left = 2 *i+ 1 ) <= len){ //判斷當前父節點有無左節點(即有無孩子節點,left爲左節點) right = left + 1 ; //右節點 j = left; //j"指針指向左節點" if (j < len && arr[left] < arr[right]) //右節點大於左節點 j ++; //當前把"指針"指向右節點 if (arr[i] < arr[j]) //將父節點與孩子節點交換(如果上面if爲真,則arr[j]爲右節點,如果爲假arr[j]則爲左節點) swap(arr,i,j); else //說明比孩子節點都大,直接跳出循環語句 break ; i = j; } } public static void swap( int [] arr, int i, int len){ int temp = arr[i]; arr[i] = arr[len]; arr[len] = temp; } public static void main(String[] args) { int array[] = { 20 , 50 , 20 , 40 , 70 , 10 , 80 , 30 , 60 }; System.out.println( "排序之前:" ); for ( int element : array){ System.out.print(element+ " " ); } heapSort(array); System.out.println( "\n排序之後:" ); for ( int element : array){ System.out.print(element+ " " ); } } } |
輸出:
排序之前: 20 50 20 40 70 10 80 30 60 排序之後: 10 20 20 30 40 50 60 70 80