排序算法-堆排序

Posted 梦想田园

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法-堆排序相关的知识,希望对你有一定的参考价值。

/*
堆排序的基本思想:将所有元素初始化一个最大堆,然后将第一个元素即最大元素与最后一个元素交换;
再对前n-1个元素调整为一个最大堆,就这样依次进行,每次都是把最大元素放到最后边。
*/
void MaxHeapify(int*list,int size,int root)

    int lChild=2*(root+1)-1,rChild=lChild+1;//根节点的左右孩子节点
    while(rChild<size)//如果右孩子节点存在
    
        if(list[root]>=list[lChild]&&list[root]>=list[rChild])//如果根节点大于左右孩子节点表明以root为根节点的树已经为最大堆
            return;
        if(list[lChild]>list[rChild])//如果左孩子大,则选左孩子作为根节点
        
            int temp=list[lChild];
            list[lChild]=list[root];
            list[root]=temp;
            root=lChild;
        
        else//右孩子大
        
            int temp=list[rChild];
            list[rChild]=list[root];
            list[root]=temp;
            root=rChild;
        
        lChild=2*(root+1)-1;
        rChild=lChild+1;
    
    if(lChild<size)//如果只有左孩子存在,说明已到最后
    
        if(list[lChild]>list[root])
        
            int temp=list[lChild];
            list[lChild]=list[root];
            list[root]=temp;
        
    


//采用迭代实现的堆排序
void HeapSortByIteration(int*list,int size)

    int last;//最后一个有孩子的节点
    if((size-1)%2==0)//该节点既有左孩子,又有右孩子
        last=(size-1-2)/2;
    else
        last=(size-1-1)/2;
    for(int i=last;i>=0;i--)//初始化最大堆
        MaxHeapify(list,size,i);
    while(size>1)
    
        //交换根元素和最后一个元素的位置
        int temp=list[0];
        list[0]=list[size-1];
        list[size-1]=temp;
        MaxHeapify(list,--size,0);
    



//采用递归实现的堆排序存在有失效率的问题,看如下代码
//相当于是每次都要对堆进行一次初始化
void HeapSortByRecursion(int*list,int size)

    if(size==1)
        return;
    int last;//最后一个有孩子的节点
    if((size-1)%2==0)//该节点既有左孩子,又有右孩子
        last=(size-1-2)/2;
    else
        last=(size-1-1)/2;
    for(int i=last;i>=0;i--)//初始化最大堆
        MaxHeapify(list,size,i);
    //交换根元素和最后一个元素的位置
    int temp=list[0];
    list[0]=list[size-1];
    list[size-1]=temp;
    HeapSortByRecursion(list,--size);


//堆排序的时间复杂度分析
/*
1.堆排序的时间主要由两部分组成,一部分是建堆时间,另一部分是调整堆的时间。
建堆的时间是O(n),调整堆的时间为O(nlogn)。至于建堆时间可用数学公式进行推导,例如有(1/2)n的元素进行了一次比较,
(1/4)n的元素进行了进行了2次比较,(1/8)n的元素进行了3次比较,....,于是可推出最终的总比较次数O(n);至于调整堆的时间
由于树的高度为log(n),大部分节点都进行了log(n)次的比较,因此时间为O(nlogn)。
2.仔细分析会发现堆排序对于数据的初始顺序状态并不太敏感,即无论初始状态怎么样都要首先建立一个最大堆,所以堆排序的最好最坏的时间
复杂度均为nlog(n)。
3.由于建堆的时间比较多,因此堆排序并不太适合排序元素量比较少的情况
*/

以上是关于排序算法-堆排序的主要内容,如果未能解决你的问题,请参考以下文章

排序算法堆排序及有界堆排序Java实现及分析

排序算法总结之堆排序

数组各种排序算法和复杂度分析

插入排序(直接插入排序希尔排序);交换排序(冒泡排序快速排序);选择排序(简单选择排序堆排序);归并排序和基数排序;基于关键词比较的排序算法下界分析

我的堆排序算法时间复杂度分析是不是正确?

算法分析-堆排序 Heap Sort