=堆是一种数据结构,实际上是一渴完全二叉树,它满足以下性质:
对于大顶堆而言,其所有的父节点都大于其子节点。
基本思想:
1、按照下标建立一棵完全二叉树
2、从最后一个非叶子节点开始与其左右孩子比较,将三者最大的点交换为父节点。每个非叶子节点都这样比较,直到根结点。
3、此时根结点一定为最大的节点,将该节点与最后一个节点交换,重复2,直到所有节点都完成上述操作为止。
具体实现:
#include <cstdio>
using namespace std;
void swap(int &a, int &b){
int tmp = a;
a = b;
b = tmp;
}
void Heap_Adjust(int *a, int cur, int len){
int lchild = cur * 2;
int rchild = cur * 2 + 1;
int max_ind = cur;
if(cur <= len / 2){//只对非叶子节点进行操作
if(lchild <= len && a[lchild] > a[max_ind])
max_ind = lchild;
if(rchild <= len && a[rchild] > a[max_ind])
max_ind = rchild;
if(max_ind != cur){
swap(a[max_ind], a[cur]);
Heap_Adjust(a, max_ind, len);//避免交换后改变了子树堆的结构
}
}
}
void Build_Heap(int *a, int len){//初始化堆
for(int i = len / 2; i >= 1; i--)
Heap_Adjust(a, i, len);
}
void HeapSort(int *a, int len){
Build_Heap(a, len);
for(int i = len; i >= 1; i--){
swap(a[i], a[1]);
Heap_Adjust(a, 1, i-1);//交换完成后,大小要减1,即把完成排序的点剔除二叉树
}
}
int main()
{
int a[] = {0, 3, 2, 1, 5, 6, 3};//下标要从1开始
int len = sizeof(a) / sizeof(int) - 1;
HeapSort(a, len);
for(int i = 1; i <= len; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}