排序問題 堆排序

2021-07-11 04:28:30 字數 1551 閱讀 8835

堆排序是基於優先佇列(使用基於陣列的大頂堆或者小頂堆)的排序,是乙個「建堆->刪除->調整->刪除->調整…」的過程。在n個元素組成的二叉堆中,建堆的時間複雜度是o(n),之後執行n次刪除堆頂元素和調整(時間複雜度為o(logn)),將每次刪除的元素一次放入乙個序列中便得到了乙個有序數列,時間複雜度為o(n)+o(nlogn),取高次即時間複雜度為o(nlogn)。

為了降低空間複雜度,使用了如下的策略:堆使用的陣列的大小是固定的,在每次刪除堆頂元素後,堆的size減掉了1,也就是堆向前縮了1個位置,因此可以使用堆最後的單元來存放剛剛刪去的元素。這個時候建立大頂堆,每次刪的的是序列中的最大值,當堆中元素為0時,整個陣列中的元素就是有序的了。過程如下圖所示:

1、構建大頂堆

2、刪除堆頂元素8,將其交換到末尾。堆的大小減了1

3、通過交換,將目前堆中最大值放在堆頂

n、刪完堆中最後乙個元素,便得到了有序的序列

原始碼如下:

#define left_child(i) (2 * (i) + 1)
/*下濾的操作,一次只處理乙個從上層傳遞過來的節點,在該節點到葉節點的

* 路徑上進行下濾的操作,將較小的節點向著較大的孩子節點的路徑走一步,

* 走到父節點不小於孩子節點時候停止。

* 功能:應用與建堆*/

void percolate_down(int arr, int i, int count)

if(tmp < arr[child])

else

}arr[i] = tmp;

}

/*使用乙個陣列進行堆排序*/

void heap_sort(int arr, int count)

/*將大頂堆根上元素放在陣列最後,堆尺寸減一*/

for(i = count - 1; i > 0; i--)

}

依然使用前邊三個演算法使用的隨機數檔案,先輸入10w的隨機數,實際測試結果如下:

對90w的資料進行排序時間如下:

堆排序問題

堆,本質上是乙個完全二叉樹,可以用陣列來表示,這樣非常的方便。最大堆 從陣列的第一號開始排,a 0 為空,方便計算。那麼ai a2i ai a 2i 1 那麼就是最大堆 最小堆 從陣列的第一號開始排,a 0 為空,方便計算。那麼ai a2i ai a 2i 1 那麼就是最小堆。ifndef dui ...

堆排序問題

給出乙個記錄序列,用堆排序的方法將其進行公升序排列,輸出結果,輸出時要求有文字說明。請任選一種語言編寫程式實現上述演算法,並分析其演算法複雜度 堆排序 堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為o nlogn 它也是不穩定排序。首先簡單...

堆排序(解決排序問題)

我之前的文章解析過排序的幾種方法,這次的堆排序原理很好理解,但 的實現並不簡單,我覺得不適合入門。堆排序的實現實際上是把根節點提取出來,不管是最大堆還是最小堆,根節點永遠是極值。乙個交換函式 在 中實現交換。向下調整函式 它的作用是調整函式使它符合堆的特點。乙個建立堆的函式 刪除函式 每次刪除極值。...