##以大堆为例:
###heap.h
#pragma once
#include<stdio.h>
#include<windows.h>
#include<assert.h>
typedef int HeapDataType;
typedef struct heap//堆在物理结构上看就是一个数组,只是我们把他抽象成树状结构
{
HeapDataType *_array;//数组指针
size_t size;//当前个数
size_t capacity;//最大容量
}heap;
void HeapAdjustDown(heap *hp, int root)
{
assert(hp);
assert(root < (int)(hp->size));
int parent = root;
int child = root * 2 + 1;
while (child < (int)(hp->size))
{
if (child + 1 < (int)(hp->size) && hp->_array[child + 1] > hp->_array[child])
{
child++;
}
if (hp->_array[parent] < hp->_array[child])
{
HeapDataType tmp = hp->_array[child];
hp->_array[child] = hp->_array[parent];
hp->_array[parent] = tmp;
}
parent = child;
child = parent * 2 + 1;
}
}
//从child下标的成员向上调整,在插入数据中用到
void HeapAdjustUp(heap *hp, int child)
{
assert(hp);
int parent = (child - 1) / 2;
while (parent)
{
if (hp->_array[parent] < hp->_array[child])
{
HeapDataType tmp = hp->_array[child];
hp->_array[child] = hp->_array[parent];
hp->_array[parent] = tmp;
}
child = parent;
parent = (child - 1) / 2;
}
if (hp->_array[parent] < hp->_array[child])
{
HeapDataType tmp = hp->_array[child];
hp->_array[child] = hp->_array[parent];
hp->_array[parent] = tmp;
}
child = parent;
parent = (child - 1) / 2;
}
//堆的初始化
void HeapInit(heap *hp, HeapDataType *_arr, size_t size)
{
//给hp->_array开辟等同于数组arr的空间,吧arr的值依次给给array即可
assert(_arr);
assert(size > 0);
hp->_array = (HeapDataType *)malloc(sizeof(HeapDataType)*size);
assert(hp->_array);
HeapDataType *cur = hp->_array;
hp->size = size;
hp->capacity = size;
for (size_t i = 0;i < size;i++)
{
cur[i] = _arr[i];
}
}
//往堆中新插入数据,需考虑增容问题,插入新数据后堆仍然不改变排列规则
void HeapPush(heap *hp, HeapDataType x)
{
assert(hp);
if (hp->size == hp->capacity)
{
hp->capacity *= 2;
hp->_array = realloc(hp->_array, hp->capacity * sizeof(HeapDataType));
}
hp->_array[hp->size] = x;
HeapAdjustUp(hp, (int)(hp->size));
hp->size++;
}
//删除堆顶数据,删除后仍不改变排列规则
void HeapPop(heap *hp)
{
assert(hp);
if (hp->size == 0)
{
printf("the heap is empty");
return;
}
hp->_array[0] = hp->_array[hp->size - 1];
hp->size--;
HeapAdjustDown(hp, 0);
}
//返回堆中的数据个数
size_t Heap_Size(heap *hp)
{
assert(hp);
return hp->size;
}
//判断堆是否为空,为空返回1,非空返回0
int HeapEmpty(heap *hp)
{
assert(hp);
if (hp->size == 0)
{
return 1;
}
return 0;
}
//返回堆的堆顶数据,(这是堆的意义所在,能在海量数据中提取最大或最小且高效)
HeapDataType HeapTop(heap *hp)
{
assert(hp);
assert(hp->size);
return hp->_array[0];
}
//堆排序
void HeapSort(heap *hp)
{
assert(hp);
int root = (hp->size - 1 - 1) / 2;
int child = hp->size - 1;
while (root>=0)
{
HeapAdjustDown(hp, root);
root--;
}
}
//从root下标的成员向下调整,向下调整的前提是他和她的左右孩子已经构成大(小)堆。
###test.c
#include"heap.h"
void test()
{
heap hp;
HeapDataType arr[] = { 9,17,65,23,45,78,87,53,31 };
HeapDataType arr1[] = { 87,78,53,45,65,9,31,17,23 };
size_t size1 = sizeof(arr) / sizeof(HeapDataType);
HeapInit(&hp, arr, size1);
HeapSort(&hp);
HeapPush(&hp, 50);
HeapPop(&hp);
for (size_t i = 0;i < (hp.size);i++)
{
printf("%d ", hp._array[i]);
}
printf("\n堆数据个数%u", Heap_Size(&hp));
printf("\n堆顶元素:%d", HeapTop(&hp));
printf("\n是否为空:%d", HeapEmpty(&hp));
}
int main()
{
test();
system("pause");
return 0;
}