堆排序(大根堆对应升序的原理)

定义

堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

在这里插入图片描述

应用

排序 :堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为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);              // 将未完成排序的部分继续进行堆排序
        }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章