核心思想:
要求升序输出,也就是从小到大排列
1.建大堆:
关键:在于向下调整
2.建好大堆后,循环删除堆顶元素
关键在于:堆顶元素与最后一个元素进行交换
1.sort.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void Swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
return;
}
void PrintArray(int array[], int size)
{
printf("打印数组结果:\n");
int i = 0;
for (; i < size; ++i) {
printf("%d ", array[i]);
}
printf("\n");
}
/*****************************************************
* 堆排序
* 时间复杂度:O(NlogN)
* 空间复杂度:O(1)
* 稳定性:不稳定排序
******************************************************/
// 建立一个大堆,要求父节点大于左右子树
// 向下调整
// index 表示从当前下标开始进行调整
void AdjustDown(int array[], int size, int index)
{
int parent = index;
int child = 2 * parent + 1; // 左子树
while (child < size) {
// 先拿左右子树进行比较,看谁比较大,然后再拿大的和父节点进行比较
if (child + 1 < size && array[child + 1] > array[child]) {
// 右子树比左子树大,就让 child 指向右子树
child = child + 1;
}
// 此时下标为child的结点是左右子树中最大的,
// 因此用大的孩子结点和父结点进行比较,若孩子结点大于父节点则进行交换
if (array[child] > array[parent]) {
Swap(&array[child], &array[parent]);
}
else
{
// 此时调整就调整完了
break;
}
// 继续向下调整,直到 child >= size(最后一个结点的下标最大,为 size-1)
parent = child;
child = 2 * parent + 1;
}
}
// 创建大堆: 重点在向下调整
void HeapCreate(int array[], int size)
{
if (size <= 1) {
return;
}
// 下沉式调整,需要从后往前遍历
// 从最后一个非叶子结点开始遍历
// size - 1 表示最后一个元素的下标
// 拿着这个下标 - 1 / 2 就得到了当前元素的父节点即(size - 1 - 1) / 2
int i = (size - 1 - 1) / 2;
for (; i >= 0; --i) {
AdjustDown(array, size, i);
}
}
// 堆删:将堆顶元素与最后一个元素交换,然后将元素个数减去一,最后进行向下调整
void HeapPop(int array[], int size) {
if (size <= 1) {
return;
}
// 关键在于将堆顶元素与最后一个源交换
// 向下调整时,元素个数 - 1,即相当于删除了一个元素,破坏了堆,要进行调整
Swap(&array[0], &array[size -1]);
AdjustDown(array, size - 1, 0);
}
// 堆排序:升序,即从小到大排列
// 建大堆,循环删除堆顶元素
void HeapSort(int array[], int size)
{
if (size <= 1) {
return;
}
// 1. 建立大堆
HeapCreate(array, size);
// 2. 循环删除堆顶元素,
// 每删除一个元素,就是将最大的值放在堆尾
int i = 0;
for (; i < size; ++i) {
HeapPop(array, size - i);
}
}
/*****************************************************
* 以下为测试代码
*****************************************************/
void TestHeapSort()
{
int array[] = {53, 17, 78, 9, 45, 65, 87, 23, 31};
int size = sizeof(array) / sizeof(array[0]);
HeapSort(array, size);
PrintArray(array, size);
}
2.Main.c
#include "sort.h"
int main()
{
TestHeapSort();
system("pause");
return 0;
}
3.截图