C++实现堆排序

堆排序思路:

     1、对传进来的数组, 进行堆调整(保证它是一个堆),即从倒数第一个根节点开始调整,例如长度为n,就从m = (n -1)/2 的位置开始向前调整。

     2、具体堆调整规则Heapify(int * arr, int len, int m)//len 表示 arr 长度,m代表从第m个开始调整,以代码为例(建大根堆),找到根节点和子节点的最大值,并且把最大值交换给根节点,如果子节点比根节点大则继续向下调整。故堆调整时间复杂度为log(n),那么建堆的时间复杂度就是n*log(n)。 

    3、建堆结束后,使顶堆跟最后一个元素交换,这里 --i 达到弹出的效果,也就是i + 1到len-1的范围都是已经排好序的,再重新调整使符合大根堆,直到排序完毕

void  Heapify(int* arr, int len, int m)//len 表示 arr 长度,m代表从第m个开始调整
{
    if (m >= len)
    {
        return;
    }
    int left = m * 2 + 1;//找到左子节点
    int right = m * 2 + 2;//找到右子节点

    int max = m;

    if (arr[left] > arr[max] && left < len)
        max = left;
    if (arr[right] > arr[max] && right < len)
        max = right;

    if (max != m)
    {
        swap(arr[max], arr[m]);
        Heapify(arr, len, max);
    }
}

void  Heapify_build(int* arr, int len)//len 表示 arr 长度
{
    //从倒数第一个根节点开始往前调整
    int last_g_node = (len - 1) / 2;
    for (int i = last_g_node; i >= 0; i--)
    {
        Heapify(arr, len, i);
    }
}

void  Heapify_Sort(int* arr, int len)//len 表示 arr 长度
{
    Heapify_build(arr, len);//保证该数组是一个堆
    for (int i = len - 1; i >= 0; i--)
    {
        swap(arr[0], arr[i]);//把第一个元素和第i个元素交换
        Heapify(arr, i, 0);
    }
}

void Test_heap()
{
    int arr[] = { 4,5,3,8,7,9,6,1,0 };
    int len = sizeof(arr) / sizeof(arr[0]);
    Heapify_Sort(arr, len);

    std::cout << std::endl;
    for (int i = 0; i < len; i++)
    {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
}

4、算法分析

时间复杂度:

  1. 最好:O(n log n)
  2. 最坏:O(n log n)
  3. 平均:O(n log n)

空间复杂度:O(1)

稳定性:不稳定

你可能感兴趣的:(data,算法,c++,数据结构)