对的定义如下:
n个关键字序列
a[1...n]
称为堆,当且仅当该序列满足:
①a[i] ≥ \geq ≥a[2i]且a[i] ≥ \geq ≥ a[2i+1]或
②a[i] ≤ \le ≤a[2i]且a[i] ≤ \le ≤ a[2i+1]
可以将该一维数组视为一棵完全二叉树,满足条件①的堆称为大根堆(大顶堆),大根堆的最大元素存放在根结点,且其任一非根结点的值小于等于其双亲结点值。满足条件②的堆称为小根堆(小顶堆),小根堆的定义刚好相反,根结点是最小元素。
通俗的来讲,将数组按层排列,每个结点大于其左右孩子结点的值称为大根堆;每个结点小于其左右孩子结点的值称为大根堆
若父结点=i
,则左孩子=2i
,右孩子=2i+1
创建初始堆:
将第一步中的根结点与末尾元素进行交换:
将剩余n-1
个元素再次进行堆排序,如此往复:
确定最后一个元素的值:
解析图:
#include "stdio.h"
typedef int ElemType;
void HeadAjust(ElemType a[], int k, int len) {
a[0]=a[k];
for (int i = 2*k; i <= len; i*=2) {
if (i<len&&a[i]<a[i+1])
i++;
if (a[0]>=a[i])
break;
else{
a[k]=a[i];
k=i;
}
}
a[k]=a[0];
}
void BuildMaxHeap(ElemType a[],int len){
for (int i = len/2; i > 0; i--) {
HeadAjust(a,i,len);
}
}
void HeapSort(ElemType a[],int len){
BuildMaxHeap(a,len);
for (int i = len; i > 1; --i) {
int temp=a[i];
a[i]=a[1];
a[1]=temp;
HeadAjust(a,1,i-1);
}
}
int main(){
int n;
ElemType a[n];
printf("一共有多少个数需要排序:");
scanf("%d",&n);
printf("请输入%d个数:",n);
for (int i = 1; i <= n; ++i) {
scanf("%d",&a[i]);
}
HeapSort(a,n);
printf("排序后为:");
for (int i = 1; i <= n; ++i) {
printf("%d\t",a[i]);
}
}
《王道:23数据结构考研复习》