/*
* @Author: hzf
* @Date: 2020-02-29 18:04:43
* @Last Modified by: hzf
* @Last Modified time: 2020-02-29 19:23:02
*/
/*
原理:
什么是堆?——完全二叉树
什么是大头堆?——父节点是最大值
二叉树的特点: index下标的左孩子下标:2*index + 1
index下标的有孩子下标:2*index + 2
index下标的父节点下标:(index-1)/2
*/
#include <iostream>
using namespace std;
void Swap(int *arr, int left, int right)
{
arr[left] = arr[left] & arr[right];
arr[right] = arr[left] & arr[right];
arr[left] = arr[left] & arr[right];
}
int Getlength(int *arr)
{
return (sizeof(arr)/sizeof(arr[0]));
}
void HeapInsert(int *arr, int i)
{
while(arr[i] > arr[(i-1)/2])//如果节点存在,并且节点的值大于父节点的值
{
Swap(arr, i, (i-1)/2);
i = (i-1)/2;//更新当前节点作为父节点
}
}
//取出堆中的最大值,并且剩余的元素依然按照堆结构进行调整
/*由堆结构的性质可以得知,堆0位置的元素即为最大值
那么将堆的首元素取出,并将末尾元素放到首元素位置,然后进行决策出合适的父节点(元素最大)
index:父节点位置
size:堆的大小
*/
void Heapify(int *arr, int index, int size)
{
int left = index*2 + 1;//左孩子
while(left < size)//左孩子存在并且没有越界
{
int largest = left+1 < size && arr[left+1] > arr[left] ? left+ : left;//决策出孩子的最大值
largest = arr[largest] > arr[index] ? largest : index;//决策出父子节点中的最大值的下标
if(largest == index)
break;
Swap(arr, largest, index);
index = largest;
left = index*2 +1;
}
}
/*堆排序原理
将一个数组按照堆结构进行排序
将末尾元素和首元素进行交换,那么最大元素到达数组末位置
将堆打大小减一,对剩余元素进行堆结构。化,交换位置
*/
void Heap_Sort(int *arr)
{
if(arr == NULL || Getlength(arr) < 2)
return;
for(int i=0; i<Getlength(arr); i++)
HeapInsert(arr, i);//将i位置的元素插入数组中的正确位置,变成大头堆
int maxValue = arr[0];//得到最大值
int size = Getlength(arr);//获取堆的大小
Swap(arr, 0, --size);//将末尾元素放在堆的首部
while(size > 0)
{
Heapify(arr, 0, size);
Swap(arr, 0, --size);
}
}
int main(int argc, char const *argv[])
{
/* code */
return 0;
}