堆排Java代碼實現
阿新 • • 發佈:2018-08-06
!= 大於 ava lse amp pri public largest turn
堆排復習:
結論:堆排算法時間復雜度為O(nlgn),額外空間復雜度為O(1);
在開始堆排序過程之前先要熟悉兩個結構
1,完全二叉樹:若設二叉樹的深度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹。(摘自百度百科)
大白話:說白了就是建立二叉樹的過程中,二叉樹每一層都是滿節點的,最後一層的節點不許中間有空缺;
2,大根堆:大根堆要求根節點的關鍵字既大於或等於左子樹的關鍵字值,又大於或等於右子樹的關鍵字值。(摘自百度百科)
大白話:就是在此堆中,任意子樹的根節點都是此子樹的最大值;
堆排序核心思想:先將無序數組建立大根堆,然後將根節點和二叉樹中最後一個節點互換,二叉樹Size--,然後重新建立大根堆,然後將根節點和二叉樹的最後一個節點互換,然後Size--,如此,一直到二叉樹的size=0,此時數組自然已經排好序;
堆排序Java實現如下:
1 package com.cmbc.test1; 2 3 import java.util.Arrays; 4 5 public class HeapSortion { 6 7 8 public static void heapSort(int[] arr){ 9 if(arr==null||arr.length<2){ 10 return; 11 } 12 //建立大根堆 13 for(int i = 0;i<arr.length;i++){14 heapInsert(arr,i); 15 } 16 //建立完大根堆之後,二叉樹的size和數組長度是一致的; 17 int size = arr.length; 18 swap(arr,0,--size); 19 while(size>0){ 20 heapify(arr,0,size); 21 swap(arr,0,--size); 22 } 23 } 24 25 publicstatic void heapInsert(int[] arr,int index){ 26 while(arr[index]>arr[(index-1)/2]){ 27 swap(arr,index,(index-1)/2); 28 index = (index-1)/2; 29 } 30 } 31 32 public static void swap(int[] arr, int i, int j) { 33 int tmp = arr[i]; 34 arr[i] = arr[j]; 35 arr[j] = tmp; 36 } 37 38 39 public static void printArray(int[] arr) { 40 if (arr == null) { 41 return; 42 } 43 for (int i = 0; i < arr.length; i++) { 44 System.out.print(arr[i] + " "); 45 } 46 System.out.println(); 47 } 48 49 public static void heapify(int[] arr,int index,int size){ 50 int left = 2*index+1; 51 while(left<size){ 52 int largest = left+1<size&&arr[left+1]>arr[left]?left+1:left; 53 largest = arr[largest]>arr[index]?largest:index; 54 if(largest==index){ 55 break; 56 } 57 swap(arr,largest,index); 58 index = largest; 59 left = largest*2+1; 60 } 61 } 62 63 public static boolean isEqual(int[] arr1, int[] arr2) { 64 if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 65 return false; 66 } 67 if (arr1 == null && arr2 == null) { 68 return true; 69 } 70 if (arr1.length != arr2.length) { 71 return false; 72 } 73 for (int i = 0; i < arr1.length; i++) { 74 if (arr1[i] != arr2[i]) { 75 return false; 76 } 77 } 78 return true; 79 } 80 81 public static int[] generateRandomArray(int maxSize, int maxValue) { 82 int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 83 for (int i = 0; i < arr.length; i++) { 84 arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 85 } 86 return arr; 87 } 88 89 public static int[] copyArray(int[] arr) { 90 if (arr == null) { 91 return null; 92 } 93 int[] res = new int[arr.length]; 94 for (int i = 0; i < arr.length; i++) { 95 res[i] = arr[i]; 96 } 97 return res; 98 } 99 100 public static void main(String[] args) { 101 int testTime = 500000; 102 int maxSize = 100; 103 int maxValue = 100; 104 boolean succeed = true; 105 for (int i = 0; i < testTime; i++) { 106 int[] arr1 = generateRandomArray(maxSize, maxValue); 107 int[] arr2 = copyArray(arr1); 108 heapSort(arr1); 109 Arrays.sort(arr2); 110 if (!isEqual(arr1, arr2)) { 111 succeed = false; 112 break; 113 } 114 } 115 System.out.println(succeed ? "正確!" : "請仔細檢查"); 116 117 int[] arr = generateRandomArray(maxSize, maxValue); 118 printArray(arr); 119 heapSort(arr); 120 printArray(arr); 121 } 122 123 }
堆排Java代碼實現