堆排序

先用維基百科的一張動圖直觀展示一下堆排序過程

bubkoo.qiniudn.com/Sorting_heapsort_anim.gif

1. 什么是堆

這里的堆是一種數據結構,不是內存分配中堆棧的堆。堆是一顆完全二叉樹,除了最底層外,每層都是滿的,這使得堆可以用數組來表示,每個節點對應數組中的一個元素。

images.cnblogs.com/cnblogs_com/kkun/201111/201111231437369307.png

2. 堆分為最大堆和最小堆:

最大堆是指所有父節點的元素值大于或等于其子元素的值(如果存在的話),因此最大堆中的最大元素必然是根節點。

最小堆是指所有父節點的元素值小于或等于其子元素的值(如果存在的話),因此最小堆中的最小元素必然為根節點。

3. 堆中節點與數組索引的對應關系如下:

left[i] = parent[2*i], ? ? ? ?right[i] = parent[2*i + 1]

4. 將堆調整為最大堆

images.cnblogs.com/cnblogs_com/kkun/201111/201111231437377256.png

5. 堆排序過程

images.cnblogs.com/cnblogs_com/kkun/201111/201111231437374682.png

以最大堆為例,需要維護最大堆、建立最大堆和進行堆排序,

maxHeapify維護最大堆,是堆排序的關鍵,時間復雜度為O(lgn)

buildMaxHeap建立最大堆,將無序輸入的數組構造為最大堆,時間復雜度為O(nlgn)

heapSort對數據進行原地排序,時間復雜度為O(nlgn)。

java實現堆排序算法代碼如下(root的index為0):

maxHeapify的過程如下圖所示:

bubkoo.qiniudn.com/building-a-heap.png

private static void maxHeapify(int[] array, int index, int heapSize) {

int iMax = index;

int iLeft = index *2+1;

int iRight = (index +1) *2;

if(iLeft < heapSize && array[iLeft] > array[iMax]) {

iMax = iLeft;

}

if(iRight < heapSize && array[iRight] > array[iMax]) {

iMax = iRight;

}

if(iMax != index) {

swap(array,iMax,index);

maxHeapify(array,iMax,heapSize);//recurse,遞歸調整

}

}

//將無序的輸入建立為最大堆

private static void buildMaxHeap(int[] array) {

intiParent = array.length/2-1;

for(int i = iParent;i >=0;i--) {

maxHeapify(array,i,array.length);

}

}

堆排序過程如下圖所示:

bubkoo.qiniudn.com/HeapSort.png

public static int[] sort(int[] array) {

int[] result = array;

buildMaxHeap(result);

intarrayLength = result.length;

for(inti = arrayLength -1;i >0;i--) {

swap(result,0,i);

maxHeapify(result,0,i);

}

return result;

}

private static void swap(int[] array, int i, int j) {

int tmp = array[i];

array[i] = array[j];

array[j] = tmp;

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • (二叉)堆數據結構是一種數組對象,可被視為一顆完全二叉樹,假設給定某個節點的下標i,則其父節點Parent(i),...
    wsdadan閱讀 366評論 0 0
  • 堆排序 堆排序基本簡介 1991年的計算機先驅獎獲得者、斯坦福大學計算機科學系教授羅伯特·弗洛伊德(Robert ...
    BlackMammba閱讀 1,857評論 0 10
  • 堆排序和快速排序一樣也是一個O(n logn)的排序算法 但是二者是不一樣的實現原理 [這是肯定的,不要pia我]...
    阿飛不理飛閱讀 751評論 0 0
  • 基礎概念#### 堆排序是比較基礎的排序算法,也是我認為比較難的一種算法,因為它的流程比較多,理解起來不會像冒泡排...
    一只小哈閱讀 28,310評論 9 32
  • 我的夢想是自由 你的自由里沒有夢想 我可以看見一只狗大便 然后寫首詩 你也可以看完一首詩 然后說她是大便 我閉上眼...
    留子堯閱讀 268評論 2 4