排序算法:堆排序

来源:互联网 发布:windows 安全模式能进 编辑:程序博客网 时间:2024/06/16 16:02

简介

堆排序(使用大堆,升序)从基本实现原理来说也是一种选择排序,它同样是确定了位置选择符合位置的元素,但是堆排序是更加优化的选择排序的版本,它利用了堆的特性。父结点的值大于子结点,且满足完全二叉树,大大提高了选择排序的效率。

算法描述

1.对无序数组建立堆(大堆)模型,
堆模型满足父结点值大于子结点值,且抽象出来的是完全二叉树;
2.把堆顶最大值与堆尾最后一个值交换,最大值就归到正确位置(有序区),之后有序区不参与调整;
3.从堆顶开始调向下整堆;
4.重复上面两步,直到数组有序。

时间复杂度

:建堆的时间复杂度为O(N),每次调整的时间复杂度为log2N(2为底),要调N-1次所以整个调整就为(N-1)*log2N(2为底),整个堆排序时间复杂度 O(N)+(N-1)O(log2N),简化后即O(N*log2N)。

堆排序1
堆排序2

代码实现

void AdjustDown(int* arr, size_t root, size_t count){//堆排序调整    size_t parent = root;    size_t child = parent * 2 + 1;    while (parent<count)    {        if (child + 1 < count&&arr[child + 1]>arr[child])        {            ++child;        }        if (child<count&&arr[child] > arr[parent])        {            std::swap(arr[child], arr[parent]);            parent = child;//向下调整父结点,继续调整            child = parent * 2 + 1;        }        else        {            break;        }    }}void HeapSort(int* arr, size_t size){//堆排序    for (int i = (size - 1) / 2; i >= 0; i--)    {//建堆过程,从数组中抽象出父结点大于子结点的完全二叉树        AdjustDown(arr, i, size);    }    size_t end = size - 1;    while (end > 0)    {        swap(arr[0], arr[end]);        AdjustDown(arr, 0, end);        end--;    }}int main(){    int a[] = {1,8,3,6,5,2,4};    HeapSort(a, sizeof(a) / sizeof(a[0]));    for (int i = 0; i < (sizeof(a) / sizeof(a[0]));i++)        cout << a[i] << ' ';    return 0;}
0 0
原创粉丝点击