【C++堆排序学习总结】

算法思路:

将数组逻辑结构理解为二叉树,然后利用大根堆特性,将二叉树调整为大根堆后,根节点即为最大的数,然后将最大的数与二叉树最后一个数交换位置,则最后一位排好位置。然后将堆的大小减一,对交换后的二叉树进行变换,使之成为大根堆,然后根节点的数即为第二大的数,将它换到现在二叉树的末尾位置,然后堆大小减一。依此类推可将所有数据排序。


存储结构:

代码

可理解为二叉树中的冒泡法。
参考左神代码编写

#include <iostream>
using namespace std;

void swap(int arr[], int index1, int index2)
{
    int temp;
    temp = arr[index1];
    arr[index1] = arr[index2];
    arr[index2] = temp;
}

void show(int a[], int len)
{
    cout << "The sort is:" << endl;
    for (int i = 0; i < len; i++)
    {
        cout << a[i] << " ";
    }
}

void heapInsert(int arr[], int index) // Generate a large root heap up
{
    while (arr[index] > arr[(index - 1) / 2])
    {
        swap(arr, index, (index - 1) / 2);
        index = (index - 1) / 2;
    }
}

void heapify(int arr[], int index, int heapsize) // Generate a large root heap down
{
    int left = 2 * index + 1;
    while (left < heapsize)
    {
        int largest = left + 1 < heapsize && arr[left + 1] > arr[left] ? left + 1 : left; // find the largest number of child nodes
        largest = arr[largest] < arr[index] ? index : largest;                            // compare the current number with the child node
        if (largest == index)
        {
            break;
        }
        swap(arr, index, largest);
        index = largest;
        left = 2 * index + 1;
    }
}

void heapsort(int arr[], int len)
{
    for (int i = 0; i < len; i++)
    {
        heapInsert(arr, i);
    }
    int heapsize = len;
    swap(arr, 0, --heapsize);
    while (heapsize > 1)
    {
        heapify(arr, 0, heapsize);
        swap(arr, 0, --heapsize);
    }
}

void duipai()
{
    int arr[] = {2, 5, 9, 7, 1, 8, 6, 4, 3, 20};
    int len = sizeof(arr) / sizeof(arr[0]);
    heapsort(arr, len);
    show(arr, len);
}

int main()
{
    duipai();
    return 0;
}

TIPS:

堆的性质:
1.是一个完全二叉树
2.每个节点的值大于(小于)子节点的值,为大(小)根堆
堆中数据用数组存放,下标为 i 的结点的父结点下标为(i-1)/2;其左右子结点分别为 (2i + 1)、(2i + 2)
堆中比较重要的两个操作是:heapinsert 和heapify。用于将二叉树调整为大根堆。


【算法】排序算法之堆排序–知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值