#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef int HPDataType;
typedef struct Heap {
HPDataType* _array;
size_t _size;
size_t _capacity;
}Heap;
void swap(HPDataType* array, int child, int parent) {
int tmp = array[child];
array[child] = array[parent];
array[parent] = tmp;
}
向下调整(以建大堆为例): 前提: --> 子树已经是一个堆
①.起始位置(父节点)
②.计算孩子位置
③.从两个孩子中选择一个最大值
④.如果孩子大于父节点,交换,更新父节点和孩子节点,继续第③步
⑤.如果没有孩子,或者父节点是 孩子中最大的,结束调整
//向下调整,建小堆
void shiftdown1(HPDataType* array, int size, int parent) {
int child = 2 * parent + 1;
while (child < size) {
if (child + 1 < size&& array[child] > array[child + 1])
child++;
if (array[child] < array[parent]) {
swap(array, child, parent);
parent = child;
child = 2 * parent + 1;
}
else
break;
}
}
//向下调整,建大堆
void shiftdown(HPDataType* array, int size, int parent) {
int child = 2 * parent + 1;
while (child < size) {
if (child + 1 < size&& array[child] < array[child + 1])
child++;
if (array[child] > array[parent]) {
swap(array, child, parent);
parent = child;
child = 2 * parent + 1;
}
else
break;
}
}
void HeapCreat(Heap* hp, HPDataType* array, int size) {
hp->_array = (HPDataType*)malloc(sizeof(HPDataType)*size);
memcpy(hp->_array, array, sizeof(HPDataType)*size);
hp->_capacity = size;
hp->_size = size;
for (int parent = (size - 2) / 2; parent >= 0; parent--) {
shiftdown(hp->_array, size, parent);
}
}
向上调整(以建大堆为例): 前提-->除过最后节点,其它节点构成的子结构已经是一个堆
①.起始位置
②.计算父亲的位置
③.比较起始位置和父亲位置的大小,如果起始位置大于父节点,交换,更新起始位置,继续执行第②步
④.没有父亲,或者起始位置小于父节点,结束调整
//向上调整,建小堆
void shiftup1(HPDataType* array, int child) {
int parent = (child - 1) / 2;
while (child > 0) {
//前提是小根堆已经建好
if (array[child] < array[parent]) {
swap(array, child, parent);
child = parent;
parent = (child - 1) / 2;
}
else
break;
}
}
//向上调整,建大堆
void shiftup(HPDataType* array, int child) {
int parent = (child - 1) / 2;
while (child > 0) {
//前提是大根堆已经建好
if (array[child] > array[parent]) {
swap(array, child, parent);
child = parent;
parent = (child - 1) / 2;
}
else
break;
}
}
//尾插
void HeapPush(Heap* hp,HPDataType data) {
//检查容量
if (hp->_size == hp->_capacity) {
hp->_capacity *= 2;
hp->_array = (HPDataType*)realloc(hp->_array, sizeof(HPDataType)*hp->_capacity);
}
//尾插
hp->_array[hp->_size++] = data;
//向上调整
shiftup(hp->_array, hp->_size - 1);
}
//删除堆顶元素
void HeapPop(Heap* hp) {
if (hp->_size > 0) {
//交换:堆顶和最后一个叶子
swap(hp->_array, 0, hp->_size - 1);
//尾删:实际删除的是堆顶元素
//删除效率高:O(1)
hp->_size--;
//向下调整
shiftdown(hp->_array, hp->_size, 0);
}
}
//获取堆顶元素
HPDataType HeapTop(Heap* hp) {
return hp->_array[0];
}
//判空
int HeapEmpty(Heap* hp) {
if (hp->_size == 0)
return 1;
return 0;
}
//堆打印
void HeapPrint(Heap* hp) {
for (size_t i = 0; i < hp->_size; i++) {
printf("%d ", hp->_array[i]);
}
printf("\n");
}
void test() {
Heap hp;
int array[11] = { 100,50,30,20,25,18,10,5,15,21,23 };
HeapCreat(&hp, array, 11);
HeapPrint(&hp);
}
void test1() {
Heap hp;
int array[11] = { 100,50,30,20,25,18,10,5,15,21,23 };
int n = sizeof(array) / sizeof(array[0]);
HeapCreat(&hp, array, n);
HeapPrint(&hp);
HeapPush(&hp, 7);
HeapPrint(&hp);
HeapPop(&hp);
HeapPrint(&hp);
}
void test2() {
Heap hp;
int array[11] = { 100,50,30,20,25,18,10,5,15,21,23 };
int n = sizeof(array) / sizeof(array[0]);
HeapCreat(&hp, array, n);
HeapPrint(&hp);
while (HeapEmpty(&hp) != 1) {
printf("%d\n",HeapTop(&hp));
HeapPop(&hp);
}
}
//堆排序
void HeapSort(int* array, int n) {
for (int i = (n - 2) / 2; i >= 0; i--) {
shiftdown(array,n,i);
}
while (n > 1) {
swap(array, 0, n - 1);
n--;
shiftdown(array, n, 0);
}
}
void test3() {
int array[11] = { 100,50,30,20,25,18,10,5,15,21,23 };
int n = sizeof(array) / sizeof(array[0]);
HeapSort(array, n);
for (int i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
}
int main() {
//test();
//test1();
//test2();
test3();
system("pause");
return 0;
}