本文将会向您介绍关于堆Heap的实现
tips:本文具体步骤的顺序并不是源代码的顺序
typedef int HPDataType;
typedef struct Heap
{
HPDataType* _a;
int _size;
int _capacity;
}Heap;
void HeapCreate(Heap* hp, HPDataType* a, int n)
{
hp->_a = NULL;
hp->_size = 0;
hp->_capacity = 0;
}
//扩容
void CheckCapacity(Heap* hp)
{
if (hp->_capacity == hp->_size)
{
int newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;
HPDataType* tmp = (HPDataType*)realloc(hp->_a, sizeof(HPDataType) * newcapacity);
if (tmp == NULL)
{
perror("malloc fail");
return;
}
hp->_a = tmp;
hp->_capacity = newcapacity;
}
}
// 堆的判空
bool HeapEmpty(Heap* hp)
{
assert(hp);
return hp->_size == 0;
}
解析:这里提供了一个swap函数用于向上调整和向下调整时交换数据
//交换
void swap(int* a, int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
每次插入的数据都会进行向上调整,将一串数据建成小堆/大堆
// 堆的插入
void HeapPush(Heap* hp, HPDataType x)
{
CheckCapacity(hp);
hp->_a[hp->_size] = x;
hp->_size++;
Adjustup(hp->_a, hp->_size - 1);
}
以小堆为例,当a[child] a[parent]就是大堆
//向上调整
void Adjustup(int* a, int child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
if (a[child] < a[parent])
{
swap(a, &a[child], &a[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
// 堆的删除 删除堆顶
void HeapPop(Heap* hp)
{
assert(hp);
assert(!HeapEmpty(hp));
swap(hp->_a, &(hp->_a[0]), &(hp->_a[hp->_size - 1]));
--hp->_size;
//向下调整
AdjustDown(hp->_a, hp->_size, 0);
}
解析:当我们删除堆顶数据的时候进行向下调整,n:堆的数据个数,利用parent计算出child下标
//向下调整
void AdjustDown(int* a, int n, int parent)
{
//计算左child,相当于(child = leftchild)
int child = parent * 2 + 1;
//当逐步地向下调整,child会越来越大,child不能超过堆数据个数
while (child < n)
{
//向下调整的时候右child可能越界
//找左右child小的那一个进行与a[parent]比较
if (child + 1 < n && a[child + 1] < a[child])
{
//若是默认的child(leftchild) > a[child + 1]
++child;
}
//可调整<(小堆)为>(大堆)
if (a[child] < a[parent])
{
swap(a, &a[child], &a[parent]);
//向下调整
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
// 堆的销毁
void HeapDestory(Heap* hp)
{
free(hp->_a);
hp->_a = NULL;
hp->_capacity = 0;
hp->_size = 0;
}
// 取堆顶的数据
HPDataType HeapTop(Heap* hp)
{
assert(hp);
assert(!HeapEmpty(hp));
return hp->_a[0];
}
// 堆的数据个数
int HeapSize(Heap* hp)
{
assert(hp);
return hp->_size;
}
#include
#include
#include
typedef int HPDataType;
typedef struct Heap
{
HPDataType* _a;
int _size;
int _capacity;
}Heap;
// 堆的构建
void HeapCreate(Heap* hp, HPDataType* a, int n)
{
hp->_a = NULL;
hp->_size = 0;
hp->_capacity = 0;
}
//扩容
void CheckCapacity(Heap* hp)
{
if (hp->_capacity == hp->_size)
{
int newcapacity = hp->_capacity == 0 ? 4 : hp->_capacity * 2;
HPDataType* tmp = (HPDataType*)realloc(hp->_a, sizeof(HPDataType) * newcapacity);
if (tmp == NULL)
{
perror("malloc fail");
return;
}
hp->_a = tmp;
hp->_capacity = newcapacity;
}
}
// 堆的判空
bool HeapEmpty(Heap* hp)
{
assert(hp);
return hp->_size == 0;
}
//交换
void swap(int* a, int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//向下调整
void AdjustDown(int* a, int n, int parent)
{
int child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n && a[child + 1] < a[child])
{
++child;
}
if (a[child] > a[parent])
{
swap(a, &a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
//向上调整
void Adjustup(int* a, int child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
if (a[child] > a[parent])
{
swap(a, &a[child], &a[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
// 堆的销毁
void HeapDestory(Heap* hp)
{
free(hp->_a);
hp->_a = NULL;
hp->_capacity = 0;
hp->_size = 0;
}
// 堆的插入
void HeapPush(Heap* hp, HPDataType x)
{
CheckCapacity(hp);
hp->_a[hp->_size] = x;
hp->_size++;
Adjustup(hp->_a, hp->_size - 1);
}
// 堆的删除 删除堆顶
void HeapPop(Heap* hp)
{
assert(hp);
assert(!HeapEmpty(hp));
swap(hp->_a, &(hp->_a[0]), &(hp->_a[hp->_size - 1]));
--hp->_size;
//向下调整
AdjustDown(hp->_a, hp->_size, 0);
}
// 取堆顶的数据
HPDataType HeapTop(Heap* hp)
{
assert(hp);
assert(!HeapEmpty(hp));
return hp->_a[0];
}
// 堆的数据个数
int HeapSize(Heap* hp)
{
assert(hp);
return hp->_size;
}
int main()
{
int arr[] = { 60, 32, 50, 65, 70, 100};
Heap hp;
HeapCreate(&hp, arr, sizeof(arr) / sizeof(arr[0]));
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
HeapPush(&hp, arr[i]);
}
while (!HeapEmpty(&hp))
{
int top = HeapTop(&hp);
printf("%d\n", top);
HeapPop(&hp);
}
}
本文的分享就到这里啦,如果本文存在疏漏或错误的地方还请您能够指出!