堆排序 梳理思路+代码实现

最近在复习排序方法,学到堆排序的时候有点混乱,所有写一写梳理一下。

(以最大堆为例)

简单来说,堆排序就是先创建一个最大堆,再对所有的非叶结点进行这样的操作:将其与此时的根结点调换位置,再使该结点满足最大堆定义。

最终就完成了对数组中存储的数据的排序,数组中的数据就是按顺序存储的。

下面结合代码说一说:

(在理解代码时,最好脑中想着一个完全二叉树的样子,光想数组的话不好理解)

这个函数是使某结点满足最大堆定义,是创建堆和进行堆排序的工具

void CreateHeap(int a[],int root,int length)   //使非叶结点root满足最大堆定义
                                               //前提是其左右孩子已经都是最大堆
{
    int i,j,flag;
    int temp;
    i=root;        //i为要建堆的结点下标
    j=2*i+1;       //j是要建堆结点的左孩子
    temp=a[i];     //先把当前结点值保存在temp中
    flag=0;        //是否满足最大堆的标志 为避免交换导致已调整好的子树不满足最大堆定义

    while(j<length && flag!=1)  //沿较大孩子向下筛选,找到所有孩子中最大的那个
    {
        if(j<length-1 && a[j]<a[j+1])
            j++;       //令j表示较大孩子
        if(temp>a[j])  //若当前结点值大于较大孩子
            flag=1;    //标志该结点已满足最大堆定义
        else         //若当前结点值小于等于较大孩子,则该结点不满足最大堆定义,要将较大孩子与该结点调换
        {
            a[i]=a[j]; //把较大孩子值赋给当前结点
            i=j;       //令较大孩子变成当前结点
            j=2*i+1;   //j是较大孩子的左孩子,准备进入下一次循环,开始判断这个左孩子是否满足最大堆定义
        }
    }
    //此时已经找到最大孩子,保存在a[i]中,接下来将最初保存在temp中的a[i]]值赋给原来最大孩子所在的位置
    a[i]=temp;
}

然后进行堆排序

(看这个时感觉思路比较顺畅)

void Heapsort(int a[],int n)   //堆排序
{
    int i,j;
    int temp;
    //先创建一个最大堆
    for(i=(n-2)/2;i>=0;i--)  //使第一个非叶结点到根结点都满足最大堆定义
        CreateHeap(a,i,n);
    //然后正式进行排序:
    //先使原先最大堆里的根结点出来,使未排序的数据形成一个新的最大堆,再使此时的根结点出来......
    for(i=n-1;i>0;i--)
    {
        //堆顶元素与最后一个交换
        temp=a[0];
        a[0]=a[i];
        a[i]=temp;
        CreateHeap(a,0,i);  //使此时的根节点满足最大堆定义
    }
    //排好序的结点会从数组最后依次进入,最终数组中存储的是从小到大排序的数据
}

光看代码理解的话还是有些辛苦,建议能找个流程图或者自己画个图去真正地走一遍全过程,那样思路就清晰了。

希望能有所帮助,如果有错误的部分可以在评论里发出来,一定及时纠正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值