時間複雜度:o(nlogn)
在insert()操作和extractmax()操作中,時間複雜度都是logn級別的,因為shiftup()和shiftdown()操作中,不管是將元素從下到上,從上到下一層層找到合適的位置都是和層序相關的。
二叉堆 binary heap:堆總是一顆完全二叉樹
最大堆(大頂堆):堆中每個節點的值總是不大於其父節點的值。
用陣列儲存二叉堆:
索引從1開始時,某個節點i的父節點為parent(i)=i/2,其左孩子為left child(i)=2i,其右孩子為right child(i)=2i+1.
大頂堆中插入元素:shift up
大頂堆我們通過陣列來儲存,向大頂堆中新增乙個元素相當於向陣列的末尾新增乙個元素,count++。此時的堆不滿足大頂堆的定義(52>16),需要進行shift up操作將其轉化為乙個大頂堆。
我們需要將新加入的元素調整到合適的位置,使整棵二叉樹符合大頂堆的定義。具體步驟為:新加入的元素與他的父親節點比,如果父節點比新加入的元素小,則交換兩者的位置,此時52和16進行交換。
此時52可能還會比他此時的父親節點大,兩者進行比較,此時52>41,兩者進行位置交換。
此時52可能還會比他此時的父親節點大,兩者進行比較,此時52<62,兩者不用進行位置交換。
大頂堆中取出最大元素:shift down
在大頂堆中取出乙個元素只能取出最大值。當取出堆頂元素(陣列中第乙個元素)時,將陣列中最後乙個元素移到堆頂位置,count–,此時堆依然是一課完全二叉樹,但不是大頂堆,需要進行shift down操作將其轉化為乙個大頂堆。
將根節點元素的位置一步一步的往下移動,直到找到合適的位置。
左右兩個孩子進行比較,誰大就和誰換。
繼續左右兩個孩子進行比較,誰大就和誰換。此時16只有左孩子,就拿他和左孩子進行比較,此時16>15,不需要進行交換,同時shift down也就結束了。
/** * 大頂堆
* * @author cuiyongling
* @since v1.0.0
* 2020-04-14 12:55
*/public
class
maxheap
comparable
>
public
intsize()
public
boolean
isempty()
public
void
insert
(e e)
else
}private
void
shiftup
(int k)
}public e extractmax()
else
}private
void
shiftdown
(int k)if(
((e)data[k]).
compareto
((e)data[j]
)>=0)
//進行交換
e temp =
(e)data[k]
; data[k]
= data[j]
; data[j]
= temp;
k = j;}}
}
package sort;
import sort.heap.maxheap;
/** * 堆排序
* * @author cuiyongling
* @since v1.0.0
* 2020-04-14 15:55
*/public
class
heapsort
comparable
>
for(
int i =n-
1; i>=
0;i--
)for
(int i =
0;ipublic
static
void
main
(string[
] args)
heapsort.
heapsort
(arr,n);}
}
排序 堆排序(heapSort)
時間複雜度 o nlog n 空間複雜度 o 1 不穩定 把此序列對應的二維陣列看成乙個完全二叉樹。那麼堆的含義就是 完全二叉樹中任何乙個非葉子節點的值均不大於 或不小於 其左,右孩子節點的值。由上述性質可知大頂堆的堆頂的關鍵字肯定是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的。因此...
堆排序練習(Heap Sort
一.目的以及背景知識 進行堆排序練習,掌握堆的構建與輸出。堆定義 對於序列a 1,n 對於任意i都有a i a 2i a i a 2 i 1 則該序列稱為大頂堆或者最大堆。反之則成為最小堆。堆篩選或堆調整 從最後乙個葉子結點開始篩選出該節點的兄弟結點與父節點中最大或最小的元素與父節點交換。建堆演算法...
堆排序(heap sort)總結
以前學資料結構的時候,用的是嚴的書,對於堆這個結構的概念似懂非懂。往往過了一段時間後有不會。現在趁著再次學習資料結構的機會,結合網上的資料整理出自己對堆的理解。二叉堆滿足二個特性 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 1.堆是完全二叉樹。2.完全二叉樹通常用陣列儲存。3.完...