https://www.cnblogs.com/chengxiao/p/6129630.html
https://www.cnblogs.com/chengxiao/p/6129630.html
这两篇篇文章解析不错
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。
堆
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆
性质:
索引为 i 的 结点:左孩子 2*i+ 1
索引为 i 的结点 :右孩子 2*i + 2
索引为 i 的父结点: 索引为 floor((i-1)/2)
数组构建堆(完全二叉树)开始结点 length/2 -1 ,length数组长度
堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了
#include <iostream>
#include <string>
using namespace std;
//构建 最大堆
void maxHeapDown(int *arr, int curr, int length)
{
//当前指针指向位置 curr
for (int i = 2 * curr + 1; i < length;i = 2*i+1)
{
//curr 当前指向位置的 左孩子arr[i] 右孩子 arr[i+1]
if (i+1 < length && arr[i] < arr[i + 1])
i++;
if (arr[i] <= arr[curr])
break;
/*if (i < length && arr[i] > arr[i + 1])
i++;
if (arr[i] >= arr[curr])
{
break;
}*/
else
{
//指针指向节点curr 元素与 孩子交换位置
int temp = arr[i];
arr[i] = arr[curr];
arr[curr] = temp;
//指针直线位置更新
//curr = i;
}
curr = i;
}
}
void heapSort(int *arr,int length)
{
//构建堆 从非叶子节点开始调整 即 length/2-1
for (int i = length / 2 - 1; i >= 0; i--)
{
maxHeapDown(arr, i, length);
}
//交换数据
for (int j = length-1; j >0; j--)
{
int tmp = arr[0];
arr[0] = arr[j];
arr[j] = tmp;
maxHeapDown(arr, 0, j);
}
}
int main()
{
int arr[] = {20,30,40,60,70,110,90,10,150,50,80,100};
//int arr[] = {312,126,272,226,28,165,123,8,12};
int len = sizeof(arr) / sizeof(arr[0]);
cout << " " << len << endl;
heapSort(arr, len);
for (int i = 0; i < len; i++)
cout << "arr[" + to_string(i) + "]" << arr[i] << endl;
system("pause");
}