#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;
}
}
4.排序算法——堆排序源码
于 2023-07-24 14:14:11 首次发布
文章详细介绍了如何使用C++编写堆排序算法,包括整体建堆、调整子树以及升序和降序排列的选择,涉及大顶堆和小顶堆的概念,并给出了具体的时间复杂度分析。
摘要由CSDN通过智能技术生成