堆的基本操作
1、堆排序思路
我们想要对数组进行降序或者升序排序,堆的根节点的值是整个堆中的最值(最小或者最大),鉴于这一点。,将根节点与最后一个节点对换,这样根结点就是堆里的最值(最小或者最大),形成去除最值后的一个新堆(大小减1),对新堆在进行调整,使其符合堆的特性,然后在进行类似操作直到堆里只剩下一个值。此时,得到的就是排序后的数组(用最大堆可获得升序数组,用最小堆可获得降序数组)。
2、堆排序的操作
HeapSort.h
#pragma once
#include <stdio.h>
#include <windows.h>
//定义一个函数指针
typedef int(*Compare)(int a, int b);
//堆排序
void HeapSort(int *array, int size ,Compare com);
//交换元素
void Swop(int *a,int *b);
//调整堆
void AdjustHeap(int* array, int size, int parent,Compare com);
//降序
int Down(int a, int b);
//升序
int Up(int a, int b);
//测试
void test();
HeapSort.c
#include "HeapSort.h"
void HeapSort(int *array, int size, Compare com)
{
int root = (size - 2) >> 1;
int end = size - 1;
//先调整堆
while (root>=0)
{
AdjustHeap(array, size, root, com);
root--;
}
//最后一个节点与根节点交换后,end--,当根节点不满足堆的性质,调整
while (end > 0)
{
Swop(&array[0], &array[end]);
AdjustHeap(array, end, 0, com);
end--;
}
}
void Swop(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void AdjustHeap(int *array, int size, int parent, Compare com)
{
int child = (parent << 1) + 1;
while (child<size)
{
//找到两个孩子中较小的一个
if (child + 1 < size && com(array[child+1], array[child]))
{
child += 1;
}
if (com(array[child], array[parent]))
{
Swop(&array[child], &array[parent]);
parent = child;
child = (parent << 1) + 1;
}
else
{
break;
}
}
}
void Heap_Print(int *array, int size)
{
int i = 0;
for (; i < size; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}
//降序
int Down(int a, int b)
{
return a < b;
}
//升序
int Up(int a, int b)
{
return a > b;
}
//测试
void test()
{
int array[] = { 53, 17, 78, 9, 45, 65, 87, 23, 31 };
Heap_Print(array, sizeof(array) / sizeof(array[0]));
HeapSort(array, sizeof(array) / sizeof(array[0]), Down);
Heap_Print(array, sizeof(array) / sizeof(array[0]));
}