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

定义

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

堆排序(大根堆对应升序的原理)_第1张图片

应用

排序 :堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序
优先队列:(个人很喜欢用,简单方便的sql)

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

误区

根据定义,大根堆的根为最大元素也就是堆顶,那为什么要把大根堆对应升序呢?
调整的难易程度
前提 :作为一个堆结构,在输出或者输入数据以后为了维护原本的堆结构就要调整

排升序:使用大堆我们每次向下调整都可以得到剩余数据的最大值,即堆顶元。然后放到最后,使用分治的思想,当交换到最后一个结点时,数组已经排好序了。

假设排降序首先使用堆排序主要是用堆顶元素,如果使用大根堆排降序,此时堆顶的元素是最大的,当我们取出堆顶元素时,此时大根堆的性质就变了,那么下次就难以找到第二大元素,要重新建堆。

代码

#include 

using namespace std;

int heap[1000],n;

inline int read()
{
        int x=0,y=1;char c=getchar();
        while(c>'9'||c<'0') {if(c=='-') y=-1;c=getchar();}
        while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
        return x*y;
}

void adjust(int x,int count)
{
        int maxindex;
        while(x<=count/2-1)
        {
                if(x==count/2-1&&count%2==0)
                maxindex=2*x+1;
                else 
                {
                        int left_index=2*x+1,right_index=2*x+2;
                        maxindex=heap[left_index]>heap[right_index]?left_index:right_index;
                }
                if(heap[x]<heap[maxindex])
                {
                        swap(heap[x],heap[maxindex]);
                        x=maxindex;
                }
                else return;
        }
}

void Build()
{
        for(int i=n/2-1;i>=0;--i)
        adjust(i,n);
}

void show()
{
        for(int i=0;i<n;++i)
        cout<<heap[i]<<" ";
}

void heap_sort()
{
        int count=n;
        while(count>1)
        {
                swap(heap[0],heap[count-1]);
                --count;
                adjust(0,count);
        }
}

int main()
{
        n=read();
        for(int i=0;i<n;++i) heap[i]=read();
        Build();
        heap_sort();
        show();
        return 0;
} 

你可能感兴趣的:(数据结构,堆排序)