堆排序的時間複雜度為O(nlogn),相對於插入排序的O(n^2),它有很大的優勢;對歸併排序來講,時間複雜度上兩者一致,但是堆排序具有空間原址性,不用像歸併那樣還要有數組的複製操作。因此,堆排序的優點多多,
下面給出演算法導論裡堆排序的java實現。
/** * 堆排序 * */ public void heapSort(int[] A){ //先建立數組對應的最大堆 buildMaxHeap(A,A.length); for(int i = A.length -1;i> 0;i--){ //將根結點與最後一個結點交換資料 int temp = A[i]; A[i] = A[0]; A[0] = temp; //將根結點從最大堆中拿出, //通過將堆大小減1並重新維護最大堆性質來實現 maxHeapify(A,1,i); } } /**建立最大堆 * @param A * @param heapSize 堆大小, */ private void buildMaxHeap(int[] A,int heapSize){ for(int i = heapSize/2;i> 0;i--){ maxHeapify(A, i, heapSize); } } /**維護最大堆屬性的過程, * 最大堆屬性即是每個結點的值至多與其根結點一樣大 * @param A * @param i 根結點 * @param heapSize 堆大小 */ private void maxHeapify(int[] A,int i,int heapSize){ int largest = i;//用來記錄父結點以及兒子結點中最大值的index int left = 2*i;//左兒子結點 int right = left+1;//右兒子結點 if(left <= heapSize && A[left-1] > A[i-1]){ largest = left; }else{ largest = i; } if(right <= heapSize && A[right-1] > A[largest-1]){ largest = right; } if(largest != i){ int temp = A[i-1]; A[i-1] = A[largest-1]; A[largest-1] = temp; //交換之後再重新維護下以largest為根結點的堆, //使其保持最大堆屬性 maxHeapify(A,largest,heapSize); } }