算法-堆排序

1. 堆

1.1 簡介

堆又稱二叉堆(由于其它幾種堆(二項式堆,斐波納契堆等)用的較少,一般將二叉堆就簡稱為堆),在結構上可以視為一棵完全的二叉樹(不過堆又增加了最大堆和最小堆的性質,下邊1.2會講)。完全二叉樹的一個“優秀”的性質是,除了最底層之外,每一層都是滿的,這使得堆可以利用數組來表示(普通的一般的二叉樹通常用鏈表作為基本容器表示),每一個結點對應數組中的一個元素:
Parent = floor((i-1)/2),i 的父節點下標
Left = 2i + 1,i 的左子節點下標
Right = 2i+ 2,i 的右子節點下標
n/2-1以及之前的都是父節點

1.2 二叉堆一般分為兩種:最大堆和最小堆:
  • 最大堆:
    最大堆中的最大元素值出現在根結點(堆頂)
    堆中每個父節點的元素值都大于等于其孩子結點(如果存在)

  • 最小堆:
    最小堆中的最小元素值出現在根結點(堆頂)
    堆中每個父節點的元素值都小于等于其孩子結點(如果存在)

2. 堆排序

堆排序主要分三步:
(1).構建堆
(2).調整堆
(3).堆排序

具體步驟:

  • 1.將長度為n的待排序的數組進行堆有序化構造成一個大頂堆:從最后一個父節點開始(向前),將所有父節點都跟它的子節點比較,保證所有父節點大于子節點。
  • 2.將根節點與尾節點交換并輸出此時的尾節點
  • 3.將剩余的n -1個節點重新進行堆有序化,此時因為只有堆頂的數據是新換上來的,只需要它跟它的子節點比較,因為只有最上邊的是新換上來的,所以只需要跟子節點比較,一直往下沉即可。
  • 4.重復步驟2,步驟3直至構造成一個有序序列

首先需要明確一點,構建堆是在數組基礎上構建的,換句話說就是將數組抽象成一個二叉堆,而不需要另構建。
在構建堆之前需要保證一點,構建之后的結構需要堆序性質。

代碼:

void swapValue(int *arr, int i, int j)
{
    if (arr==NULL) {
        return;
    }
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
//對index所在的節點,判斷是否有子節點,如果有則比較,并交換,保證該節點比子節點都大。如果產生交換了,則交換下去的節點還需要和它的節點做同樣的判斷交換。
void maxHeapify(int *arr, int index, int len)
{
    if (arr==NULL || len<=0) {
        return;
    }
    int left = 2*index+1;//因為是二叉堆,滿足完全二叉樹的結構,所以只判斷左子樹就知道有無,子節點了
    int right = left+1;
    int max = left;
    while (left < len) {//證明有子節點
        if (right<len && arr[right]>arr[left]) {
            max = right;
        }
        if (arr[max]>arr[index]) {
            swapValue(arr, max, index);
        }
        index = max;
        left = 2*index+1;
        right = left+1;
        max = left;
    }
}


//算法堆排序:代碼是升序
void heapSort(int *arr, int len)
{
    if (arr==NULL || len<=0) {
        return;
    }
    
    //1.構建堆(數組數據滿足堆序)
    for (int i=len/2-1; i>=0; i--) {
        maxHeapify(arr, i, len);
    }
    swapValue(arr, 0, len-1);//2.首尾交換
    len--;
    
    while (len>1) {
        maxHeapify(arr, 0, len);//3.重新調整堆(滿足大頂堆),因為只有最上邊的是新換上來的,所以只需要跟子節點比較,一直往下沉即可
        swapValue(arr, 0, len-1);//4.首尾交換
        len--;
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容