堆排序

堆排序

堆的一个重要应用,堆排序,主要是将将一组数据排成有序的序列,如何实现?先将这组数据放到二叉树中建大堆,然后再把第一个数据与最后一个交换,最大的数据就在最后,然户把其余n-1个数据继续调成成大堆,再把第一个和次大的交换,每次排序后,无序的数据范围缩小1,直到最后这个无序的序列只剩最后一个数据,就会完成排序

分两步:

一:建大堆(升序)

//向下调整建大堆
void _AjustDown(int* heap, size_t root, size_t n)
{
    assert(n>0);
    int parent = root;
    int child = parent * 2 + 1;
    while (child < n)
    {
        //选较大的孩子
        if (child + 1<n && heap[child + 1] > heap[child])
        {
            child++;
        }
        //比较父亲节点与孩子节点的大小
        if (heap[child] >heap[parent])
        {
            swap(heap[child], heap[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }
    }
}

二:排序
void HeapSort(int*a, size_t n)
{
    assert(a);
    //建大堆
    for (int i = (n - 2) / 2; i >= 0; --i)
    {
        _AjustDown(a, i,n );//向下调整
    }
    //排序原理是选择排序第一个与最后一个交换,再讲第一个与次大交换,直到最后一个
    int end = n - 1;
    while (end)
    {
        swap(a[0], a[end]);//第一个与最后一个交换
        _AjustDown(a, 0, end);//调整成堆;
        --end;//第一个与次大的交换直到第一个
    }
}

其余n-1个元素继续调整为大堆,然后再排序,直到最后一个元素,此时就成为一个有序序列


完整代码

#pragma once
#include<iostream>
using namespace std;
void _AjustDown(int* heap, size_t root, size_t n)
{
    assert(n>0);
    int parent = root;
    int child = parent * 2 + 1;
    while (child < n)
    {
        //选较大的孩子
        if (child + 1<n && heap[child + 1] > heap[child])
        {
            child++;
        }
        //比较父亲节点与孩子节点的大小
        if (heap[child] >heap[parent])
        {
            swap(heap[child], heap[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }
    }
}
void HeapSort(int*a, size_t n)
{
    assert(a);
    //建大堆
    for (int i = (n - 2) / 2; i >= 0; --i)
    {
        _AjustDown(a, i,n );//向下调整
    }
    //排序原理是选择排序第一个与最后一个交换
    int end = n - 1;
    while (end)
    {
        swap(a[0], a[end]);//第一个与最后一个交换
        _AjustDown(a, 0, end);//调整成堆;
        --end;//第一个与次大的交换直到第一个
    }
}
void TestHeapSort()
{
    int a[] = { 5, 6, 3, 2, 1, 4 };
    int len = sizeof(a) / sizeof(a[0]);
    HeapSort(a, len);   
}


时间复杂度为O(N*logN)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值