演算法筆記之堆排序

2021-09-07 04:28:49 字數 2384 閱讀 9023

一、對堆排序的相關了解

1、堆排序的執行時間是

o(nlogn) ;

2、定義:

heap是一棵具有下面屬性的二叉樹——

1)它是一棵全然二叉樹。

2)每乙個結點大於或等於它的隨意乙個孩子。

備註:全然二叉樹的定義——除了最後一層沒填滿以及最後一層的葉子都是偏左放置的。其它層都是滿的二叉樹! 3

、二叉堆有兩種:最大堆和最小堆。在堆排序中我們使用的是最大堆,最小堆經常在構造優先佇列時使用。

4、一條路徑的深度指的是這條路徑的邊數。乙個結點的深度是指從根結點到該結點的路徑的長度。

二、對堆進行排序

1)加入新元素

我們能夠把堆儲存在乙個

array

list

裡。樹根在位置

0處,它的兩個孩子在位置1和

2。儲存規律例如以下,對於位置在

i的結點,它的左孩子在

2i+1

處。右孩子在

2i+2

處,而它的父親在位置

(i-1)/2處

//新增乙個元素

public void add(e object)else

currentindex = parentindex;//一路交換上去。直到根結點為止

} }

2)刪除並返回當前堆的最大值返回根元素,並重建堆,重建堆的思路是將最後面的那個元素放到根元素的位置,然後與它的最大子樹想比(之前推斷是否有左右子樹,然後再比較出左右子樹哪個更大),假設比最大子樹小,那麼交換。依次下去,直到當前元素的索引》=list的長度

public e remove()elseelse if(rightchildindex < list.size())

}//與根元素比較,根元素小則交換,否則退出迴圈,此時已經是堆了

if (list.get(currentindex).compareto(list.get(maxchildindex)) < 0) else

}//返回根元素。堆的最大值

return root;

} }

3、排序

/**

* 堆排序方法

* decription:

* @author : linjq

*/public void sort(e list)

4、測試該堆排序

public static void main(string args) ;

heapsort heapsort = new heapsort();

heapsort.sort(list);

for (int i = 0; i < list.length; i++)

system.out.print(list[i] + " ");

}

測試結果——

三、時間複雜度分析

如果我們如今有

n個元素。用

h來表示

n個元素的高度,因為堆是全然二叉樹,於是第一層有

1個結點,第二層有兩個

...第

h層至少有

1個。最多有

2^(h - 1)

個結點。

即1+2+…+2^(h -2) < n <= 1+2+…+ 2^(h-2 )+ 2^(h -1)

化簡即得:

2^(h-1) - 1 < n <= 2^h - 1

即h- 1 < log(n+1) <= h

所以log(n+1) < h<= log(n+1) +1

所以堆的高度是

o (logn)

由於remove

和add

方法最多情況下須要從根結點追蹤到葉子結點,最多耗費的時間只是是h步,

n個元素就呼叫

n次這兩個方法,因此堆排序的時間複雜度是

o(nlogn)

演算法導論筆記之堆排序

堆排序 時間複雜度nlgn 堆是一種特殊的二叉樹,最大堆 根節點的key大於其兩個孩子節點鍵值,依次類推,所以最大值為根,最小值在葉子節點處 ita定義堆的陣列表示法為1 10,所以a 0 暫用無處,比如,長度為10的堆,則用a 1 a 10 表示,建立時的長度要比實際長度多1 幾個常見操作 hea...

演算法 排序演算法之堆排序

package sortarith 堆排序 構建最大堆,堆頂即為最大元素,每次取出最大元素後,再重新構建堆,這樣再拿出次大值,迴圈往返 注意 構建堆時需要調整每個非葉子節點,確定其為子堆的最大值 而調整堆時,只需要調整堆頂元素 特例1 若所給待排序陣列array本身已是最大堆型別,可不進行構建堆,即...

演算法 排序演算法之堆排序

堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。堆排序可以說是一種利用堆的概念來排序的選擇排序。分為兩種方法 大頂堆 每個節點的值都大於或等於其子節點的值,在堆排序演算法...