4.排序算法——堆排序源码

#include <iostream>
using namespace std;
#include <assert.h>
#include <ctime>
#include <math.h>
#include <cstdlib>
#include <cstddef>
#include <malloc.h>
#include <stack>

typedef signed long int size_test;

typedef signed long int size_sort_index,size_index;
typedef signed long int size_ele,size_cpt;

enum sel_Heap
{
    Small, Big
};

template <typename T>
bool compare_value(T value1, T value2)
{
    return value1 < value2;
}



//堆排序
//这个是让无序的完全二叉树,从头到尾整体建堆,用从尾到头思想,整体建完——————时间复杂度是O(N)
void Heap_AdjustDwon_All(int* array_ptr, size_ele n, size_sort_index root_index,
    enum sel select = Order, enum sel_Heap sel_h = Big)
{
    void Heap_AdjustDwon(int* array_ptr, size_ele n, size_sort_index root_index,
        enum sel select = Order, enum sel_Heap sel_h = Big);

    //在HeapSort函数中child_index是等于parent_index * 2 + 1的,如果child_index >= n,那么就不需要判断当前parent的子节点了
     //n - 1 >= parent_index * 2 + 1   这是需要操作到子节点的关系,算出paren_index下标(索引)最大为(n /2  - 1)需要操作子节点
    for (size_sort_index i = ((size_sort_index)n) / 2 - 1; i >= 0; --i)
    {
        Heap_AdjustDwon(array_ptr, n, i, select, sel_h);
    }
}

//这个建堆,前提是 提供的root_index索引下的节点的左右两个子树是有序性的(大顶堆或者是小顶堆)
void Heap_AdjustDwon(int* array_ptr, size_ele n, size_sort_index root_index,
    enum sel select = Order, enum sel_Heap sel_h = Big)
{
    assert(NULL != array_ptr);

    size_sort_index parent_index = root_index;
    size_sort_index child_index = parent_index * 2 + 1;//默认为左子树的根节点
    while (true)
    {
        if (child_index >= n)
        {
            break;
        }
        bool get_child_index_flag = false;
        bool get_parent_index_flag = false;

        if (child_index + 1 < n)
        {
            //大小顶堆选择
            get_child_index_flag = sel_h ? (compare_value(array_ptr[child_index + 1], array_ptr[child_index]))
                : ((compare_value(array_ptr[child_index], array_ptr[child_index + 1])));

            //获取左右子树根节点最大值的节点的索引。
            child_index = (get_child_index_flag) ? child_index : (child_index + 1);
        }

        //判断该子树根节点的值与其父节点的值大小;
        get_parent_index_flag = sel_h ? (compare_value(array_ptr[parent_index], array_ptr[child_index]))
            : ((compare_value(array_ptr[child_index], array_ptr[child_index + 1])));


        //如果这个为true,就证明需要交换父子节点,如果交换完毕,则继续,否则结束
        if (get_parent_index_flag)
        {
            auto temp_value = array_ptr[parent_index];
            array_ptr[parent_index] = array_ptr[child_index];
            array_ptr[child_index] = temp_value;


            parent_index = child_index;
            child_index = parent_index * 2 + 1;
        }
        else
        {
            break;
        }
    }

}

//堆排序步骤 总体时间复杂度 (n + nlogn) 估为O(nlogn)  
void HeapSort(int* array_ptr, size_ele n, size_sort_index root_index,
    enum sel select = Order, enum sel_Heap sel_h = Big)
{
    //第一步:整体建堆----on
    void Heap_AdjustDwon_All(int* array_ptr, size_ele n, size_sort_index root_index,
        enum sel select, enum sel_Heap sel_h);
    Heap_AdjustDwon_All(array_ptr, n, root_index, select, sel_h);    //默认排升序用 Big(大顶堆)


    //第二步:多次向下调整排序;时间复杂度nlogn
    void Heap_AdjustDwon(int* array_ptr, size_ele n, size_sort_index root_index,
        enum sel select, enum sel_Heap sel_h);

    size_sort_index end = n - 1;
    while (end > 0)
    {
        //交换
        auto temp_value = array_ptr[0];
        array_ptr[0] = array_ptr[end];
        array_ptr[end] = temp_value;

        //向下调整排序
        Heap_AdjustDwon(array_ptr, end, 0, select, sel_h);

        //进行下一位换位
        --end;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小艺术生◎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值