堆排序 算法
算法思路
- 待排序元素按照大小,在二叉樹位置上排列
- 構造最大堆(最小堆)跟節點元素為所有元素最大的一個
- 每次取構造最大堆完成的根節點,并重新構造最大堆
- 重復以上步驟,直到堆中只剩下一個元素則排序完成
算法實現
void max_heap(vector<int> &arr, int beg, int end) {int dad = beg; //因為數組下標從0開始,所以son需要再+1int son = 2*beg + 1; while(son <= end) {if (son + 1 <= end && arr[son] < arr[son+1]) {son++;} if (arr[dad] > arr[son]) {//父親節點大于子節點,代表調整完畢return;} else { //交換父子節點,同時再次子節點和孫節點比較swap(arr[dad], arr[son]);dad = son;son = dad * 2 + 1;}}
}void heap_sort(vector<int> &arr) {int size = arr.size();//舒適化堆,從最后一個父親節點開始進行for (int i = size / 2 - 1; i >= 0; i--) {max_heap(arr, i, size - 1);}//初始化后arr[0]將為最大的節點for (int i = size - 1;i > 0; i -- ) {swap(arr[0],arr[i]);//先將取出最大的元素放到最后位置,重新篩選排序的最大元素max_heap(arr, 0, i - 1);//這里i-1是為了防止越界,調整堆時需要兩個孩子節點先比較}
}
算法分析
時間復雜度:初始化建立堆的過程O(n),取出最大元素后重建堆O(nlogn)
空間復雜度:O(1),原地置換swap的temp變量
總結