堆排序

假设数组索引从0开始计数:

  1. 对于任意位置i上的元素,其左子节点的索引为2i + 1,右子节点的索引为2i + 2。
  2. 对于任意位置i上的元素,其父节点的索引为(i -1) / 2(向下取整)
       10
      /  \
     5    7
    / \  /
   2  3 6

数组 a[i] 10 5 7 2 3 6

5的索引是 1 父节点(1 - 1)/ 2 = 0 左节点2x1+1 = 3

排序

1.建立最大堆:

在建立最大堆的过程中,堆的性质会被满足,即每个节点都比其子节点大(对于最大堆而言)。

确保堆顶元素为最大值。

2.交换堆顶元素与最后一个元素:

堆顶元素是最大值,将其与最后一个元素交换,相当于将当前最大值放到了已排序部分的末尾。此时最大值为有序序列。

调整堆:不断重复,下次调整不算最后的有序序列

交换之后,堆的性质可能被破坏,因为新的堆顶元素不一定是最大的了。因此,需要进行堆调整操作,将剩余元素重新构成一个最大堆。

#include<iostream>
using namespace std;
void swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;

}
// 维护最大堆
void max_heapify(int arr[], int len, int i)
{
    int max = i;
    int lson = 2 * i + 1;
    int rson = 2 * i + 2;
    if (lson < len && arr[max] < arr[lson])
    {
        max = lson;
    }
    if (rson < len && arr[max] < arr[rson])
    {
        max = rson;
    }
    if (max != i)
    {
        swap(arr[max], arr[i]);
        max_heapify(arr, len, max);
    }

}
void HeapSort(int arr[], int len)
{
    // 建立最大堆
    for (int i = (len -1)/2; i >= 0; i--)
    {
        max_heapify(arr,len,i);
    }

    // 排序
    for (int i = len - 1; i > 0; i--)
    {
        swap(arr[i],arr[0]);
        max_heapify(arr,i,0);
    }
}
void PrintfArr(int arr[], int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%d\t",arr[i]);
    }
    printf("\n");
}
int main()
{
    int arr[] = {12,23,45,65,21,12,3,1,23,4};
    int len = sizeof(arr) / sizeof(int);
    PrintfArr(arr,len);
    HeapSort(arr,len);
    PrintfArr(arr, len);


    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值