堆排序(大根堆對應升序的原理)

定義

堆是具有以下性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱爲大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值,稱爲小頂堆。如下圖:

在這裏插入圖片描述

應用

排序 :堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均爲O(nlogn),它也是不穩定排序
優先隊列:(個人很喜歡用,簡單方便的sql)

priority_queue<int, vector<int>, greater<int> > q;

誤區

根據定義,大根堆的根爲最大元素也就是堆頂,那爲什麼要把大根堆對應升序呢?
調整的難易程度
前提 :作爲一個堆結構,在輸出或者輸入數據以後爲了維護原本的堆結構就要調整

排升序:使用大堆我們每次向下調整都可以得到剩餘數據的最大值,即堆頂元。然後放到最後,使用分治的思想,當交換到最後一個結點時,數組已經排好序了。

假設排降序首先使用堆排序主要是用堆頂元素,如果使用大根堆排降序,此時堆頂的元素是最大的,當我們取出堆頂元素時,此時大根堆的性質就變了,那麼下次就難以找到第二大元素,要重新建堆。

代碼

void adjust_heap(int* a, int node, int size)
{
        int left = 2*node + 1;
        int right = 2*node + 2;
        int max = node;
        if( left < size && a[left] > a[max])
                max = left;
        if( right < size && a[right] > a[max])
                max = right;
        if(max != node)
        {
                swap( a[max], a[node]);
                adjust_heap(a, max, size);
        }
}
 
void heap_sort(int* a, int len)
{
        for(int i = len/2 -1; i >= 0; --i)
                adjust_heap(a, i, len);
 
        for(int i = len - 1; i >= 0; i--)
        {
                swap(a[0], a[i]);           // 將當前最大的放置到數組末尾
                adjust_heap(a, 0 , i);              // 將未完成排序的部分繼續進行堆排序
        }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章