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