堆排序数据结构: 数组(静态 / 动态 / 链表等)
堆排序步骤:
1. 建立大根堆/小根堆
2. 交换根节点与最后一个结点的数值,最后一个结点为有序序列
3. 重新将待排序的树调整为大根堆
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
/*大根堆:根节点的值大于左右孩子的数值*/
/*
1. 建立大根堆(检查所有的非终端结点 i<=n/2的结点 下标0舍弃不用)
2. 如果根节点不满足大根堆 那么将根节点与他最大的孩子结点交换 小元素不断下坠
3. 然后交换根节点和最后一个元素 根节点是最大的 最后一个元素是最小的
*/
//将数据填入数组中
void AddData(int *a,int d[],int n) {
for (int i = 1; i <= n; i++) {
a[i] = d[i-1];
}
}
//将以k为根结点的树调整为大根堆
void HeapAdjust(int* a, int k, int n) {
a[0] = a[k]; //临时存储该根节点的数据
//沿着数值较大的子节点向下筛选
for (int i = 2 * k; i <= n; i *= 2) {//左孩子结点
if (i < n && a[i] < a[i + 1])
i++;//右孩子大
if (a[0] > a[i]) break;
else {
a[k] = a[i];
k = i;
}
}
a[k] = a[0];
}
//建立大根堆
void BuildBigRootHeap(int *a,int n) {
for (int i = n / 2; i >=1;i--) {
HeapAdjust(a,i,n);
}
}
void Print(int *e,int n) {
for (int i = 1; i <= n; i++) {
printf("%d ",e[i]);
}
}
//堆排序:每一趟将堆顶元素加入到有序子序列与待排序序列的最后一个元素交换
//交换以后,len长度数值-1 然后在将待排序树调整为大根堆 小元素下坠的过程 然后每一趟选出一个最大的数值
void HeapSort(int *e, int n) {
for (int i = n; i >= 1; i--) {
int tmp = e[i];
e[i] = e[1];
e[1] = tmp;//交换最后一个元素和堆顶元素
HeapAdjust(e,1,i-1);
}
}
int main() {
int data[] = {53,17,78,9,45,65,87,32};//数据元素
int n = 8;
int *element = (int*)malloc(sizeof(int)*(n+1)); //0号位置不使用
AddData(element,data,n);
BuildBigRootHeap(element,n);
HeapSort(element,n);
Print(element,n);
return 0;
}