演算法與資料結構專場 堆排序是什麼鬼?

2022-04-12 10:46:59 字數 2376 閱讀 4937

【演算法與資料結構】二叉堆是什麼鬼?

假如給你乙個二叉堆,根據二叉堆的特性,你會怎麼使用二叉堆來實現堆排序呢?

我們都知道,二叉堆有乙個很特殊的節點 —-堆頂,堆頂要嘛是所有節點的最大元素,要嘛是最小元素,這主要取決於這個二叉堆是最小堆還是最大堆

今天,我們暫且選擇以最小堆來作為例子。

基於堆頂這個特點,我們就可以來實現我們的堆排序了。

大家看下面乙個例子:

對於乙個如圖有10個節點元素的二叉堆:

我們把堆頂這個節點刪除,然後把刪除的節點放在乙個輔助陣列help裡。

顯然,這個被刪除的節點,是堆中最小的節點。接下來,我們繼續刪除二叉堆的堆頂,然後把刪除的元素還是存放在help陣列裡。

顯然,第二次刪除的節點,是原始二叉堆中的第二小節點。

繼續刪除

繼續連續6次刪除堆頂,把刪除的節點一次放入help陣列。

二叉堆中只剩最後乙個節點了,這個節點同時也是原始二叉堆中的最大節點,把這個節點繼續刪除了,還是放入help陣列裡。

此時,二叉堆的元素被刪除光了,觀察一下help陣列。這是乙個有序的陣列,實際上,通過從二叉堆的堆頂逐個取出最小值,存放在另乙個輔助的陣列裡,當二叉堆被取光之時,我們就完成了一次堆排序了。

在上面的堆排序過程中,我們使用了乙個輔助陣列help。可事實上,我們真的需要輔助陣列嗎?

上篇講二叉堆的時候,我們說過。二叉堆在實現的時候,是採取陣列的形式來儲存的。

從二叉堆中刪除乙個元素,為了充分利用空間,其實我們是可以把刪除的元素直接存放在二叉堆的最後乙個元素那裡的。例如:

刪除堆頂,把刪除的元素放在最後乙個元素。

繼續刪除,把刪除的元素放在最後第二個位置

繼續刪除,把刪除的元素放在最後第三個位置

以此類推….

這樣,對於乙個含有n個元素的二叉堆,經過n-1(不用刪除n次)次刪除之後,這個陣列就是乙個有序陣列了。

所以,給你乙個無序的陣列,我們需要把這個陣列構建成二叉堆,然後在通過堆頂逐個刪除的方式來實現堆排序。

其實,也不算是刪除了,相當於是把堆頂的元素與堆尾部在交換位置,然後在通過下沉的方式,把二叉樹恢復成二叉堆。

**如下:

public

class

heapsort

//如果父節點比孩子節點小或等於,則下沉結束

if (temp <= arr[child])

break;

//單向賦值

arr[parent] = arr[child];

parent = child;

child = 2 * parent + 1;

}arr[parent] = temp;

return arr;

}//堆排序

public

static

int heapsort(int arr, int length)

//進行堆排序

for (int i = length - 1; i >= 1; i--)

return arr;

}//測試

public

static

void

main

(string args)

; system.out.println(arrays.tostring(arr));

arr = heapsort(arr, arr.length);

system.out.println(arrays.tostring(arr));}}

對於堆的時間複雜度,我就直接給出了,有興趣的可以自己推理下,還是不難的。堆的時間複雜度是 o (nlogn)。空間複雜度是 o(1)。

這裡可能大家會問,堆排序的時間複雜度是o (nlogn),像快速排序,歸併排序的時間複雜度也是 o(nlogn),那我在使用的時候該如何選擇呢?

這裡說明一下:快速排序是平均複雜度 o(logn),實際上,快速排序的最壞時間複雜度是o(n^2。),而像歸併排序,堆排序,都穩定在o(nlogn)

我給出乙個問題,例如給你乙個擁有n個元素的無序陣列,要你找出第 k 個大的數,那麼你會選擇哪種排序呢?

顯然在這個問題中,選用堆排序是最好的,我們不用把陣列全部排序,只需要排序到前k個數就可以了。至於**如何實現,這個我就不給**了,大家可以動手敲一敲。

推薦閱讀:

【演算法與資料結構】二叉堆是什麼鬼?

資料結構與演算法 堆排序

1 堆的性質 堆是一棵完全二叉樹,除最後一層外每層都是滿的 元素個數為2 i 1 根節點為第1層 最後一層如果不滿則只缺少右邊葉結點。如果按照廣度優先,即從上至下,從左至右對節點編號。根節點序號為0,節點i的父節點是 i 1 2,左子節點是2 i 1。最小堆中任意父節點不能比子節點大,最大堆中任意父...

資料結構與演算法 堆排序

基礎概念 堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為o nlogn 它也是不穩定排序。通俗理解 將待排序序列構造成乙個大頂堆,此時,整個序列的最大值就是堆頂的根節點。將其與末尾元素進行交換,此時末尾就為最大值。然後將剩餘n 1個元素重新...

資料結構與演算法 堆排序

堆排序堆排序是指利用堆這種資料結構所設計的一種排序演算法。堆是乙個近似完全二叉樹的結構,並同時滿足堆的性質 即子節點的鍵值或索引總是小於 或者大於 它的父節點,堆排序的時間複雜度為o nlogn 來自維基百科 什麼是堆 堆是一種特殊的完全二叉樹,它的性質為 任意節點大於等於或者小於等於它的左右節點。...