堆排序 SCAU c++

堆排序大体思路是:建堆,然后通过堆交换结点大小,将最大的结点放到堆最顶端,将该最大数与数组最后一位交换,不断重复这个过程,直到数组从后往前逐渐完成排序。

此题用大根堆排序和小根堆排序都行,只有一点细微上的差别。

比如每次swap交换的是数组第一位而不是最后一位,然后在adjust函数中判别条件是左右孩子结点取小的那个,父节点小于该孩子结点,那就更换,换到最后堆顶为最小的。

大根堆代码详解如下,附在代码注释中:

#include <iostream>
#include <stdio.h>

using namespace std;

void HeadAdjust(int a[],int k,int len)//每次调整都从数组第一位开始慢慢向后调整
{
    a[0]=a[k];//k为对应父节点下标

    for(int i=2*k;i<=len;i*=2)
    {
        //对于父节点和两个子节点,要更换的是子节点中更大的那一个跟父节点换
        if(i<len && a[i]<a[i+1])//如果左孩子小于右孩子
            i++;

        if(a[0]>=a[i])//如果父节点比更大的那个孩子数值还要大,就不用交换
            break;
        else
        {
            a[k]=a[i];//父节点与孩子交换
            k=i;//将k也就是下标往下移动,换到更大的结点那里,继续往下找看看还有没有需要换的结点
        }

    }

    a[k]=a[0];//此时父节点数值可以放入该位置了,因此左右孩子都比他小了

}

void BuildMaxHeap(int a[],int len)
{
        for(int i=len/2;i>0;i--)//从底向上建
        {
            HeadAdjust(a,i,len);
        }

}

void HeapSort(int a[],int len)
{
    //BuildMaxHeap(a,len);

    for(int i=len;i>1;i--)
    {
        swap(a[i],a[1]);//将大根堆的最顶端也就是数组中最大的数已处于数组第一位,与数组最后一位交换,然后就是倒数第二,倒数第三
        HeadAdjust(a,1,i-1);//然后再对堆进行交换,最后一位已经是最大的了所以不用排序了

        for(int j=1;j<=len;j++)
        {
            printf("%d ",a[j]);
        }
        printf("\n");

    }

}


int main()
{
    int n,i;
            //思路是,建堆,然后通过堆交换结点大小,将最大的结点放到堆最顶端,将该最大数与数组最后一位交换,不断重复这个过程
    scanf("%d",&n);
    int a[n+1];

    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }

    BuildMaxHeap(a,n);//先建堆,大根堆,建成完全二叉树先

    for(int j=1;j<=n;j++)
    {
        printf("%d ",a[j]);
    }
    printf("\n");

    HeapSort(a,n);//然后调堆


    return 0;
}

 

 欢迎大家在评论区留言~~

觉得有帮助的不妨点个赞

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值