版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hansionz/article/details/81984631
1.定义结构
//定义堆结构(动态线性表实现)
typedef int HTDataType;
typedef struct Heap
{
HTDataType* _a;
int _size;
int _capacity;
}Heap;
2.接口声明
//初始化堆
void HeapInit(Heap* hp, HTDataType* a, int n);
//堆的销毁(释放malloc出来的空间)
void HeapDestory(Heap* hp);
//向堆里插入一个数据
void HeapPush(Heap* hp, HTDataType x);
//弹出堆顶的数据
void HeapPop(Heap* hp);
//取堆顶数据
HTDataType HeapTop(Heap* hp);
//堆的大小
int HeapSize(Heap* hp);
//判断堆是否为空(空返回0,非空返回1)
int HeapEmpty(Heap* hp);
//向下调堆
void AdjustDown(HTDataType* a, int n, int parent);
//向上调堆
void AdjustUp(HTDataType* a, int n, int child);
//堆排序
3.函数实现
#include "Heap.h"
//交换两个数据
static void Swap(HTDataType* a, HTDataType* b)
{
HTDataType tmp = *a;
*a = *b;
*b = tmp;
}
//向下调堆
void AdjustDown(HTDataType* a, int n, int parent)
{
assert(a);
int child = 2 * parent + 1;//左孩子
while (child < n)
{
//确定比较大的那个孩子
if ((a[child] < a[child + 1])&&(child+1 != n))
{
child++;
}
//如果建大堆,如果双亲小于孩子,则交换
if (a[parent] < a[child])
{
Swap(&a[parent], &a[child]);
//调整parent和child,继续向下调堆直到叶子为止
parent = child;
child = 2 * parent + 1;
}
else
{
break;
}
}
}
//初始化堆
void HeapInit(Heap* hp, HTDataType* a, int n)
{
assert(hp);
//开辟空间
hp->_capacity = 6;
hp->_a = (HTDataType*)malloc(sizeof(HTDataType)*(hp->_capacity));
hp->_size = 0;
//建堆
//1.给堆里的数组赋值
int i = 0;
for (i = 0; i < n; i++)
{
hp->_a[i] = a[i];
hp->_size++;
}
//2.从第一个非叶子结点开始向上调整(n为数组大小,所以n-1为数组最后一个元素的下标)
for (i = (n - 2) / 2; i >= 0; i--)
{
AdjustDown(hp->_a, hp->_size, i);
}
}
//堆的销毁(释放malloc出来的空间)
void HeapDestory(Heap* hp)
{
assert(hp);
free(hp->_a);
hp->_a = NULL;
hp->_capacity = 0;
hp->_size = 0;
}
//向上调整堆
void AdjustUp(HTDataType* a, int n, int child)
{
assert(a);
int parent = (child - 1) / 2;//双亲
while (child > 0)
{
//如果建大堆,如果双亲小于孩子,则交换
if (a[parent] < a[child])
{
Swap(&a[parent], &a[child]);
//调整parent和child向上走
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
//向堆里插入一个数据
void HeapPush(Heap* hp, HTDataType x)
{
assert(hp);
//堆满了则先扩容在入堆
if (hp->_size == hp->_capacity)
{
hp->_capacity *= 2;
HTDataType* tmp = realloc(hp->_a, sizeof(HTDataType)*(hp->_capacity));
if (tmp != NULL)
{
hp->_a = tmp;
}
}
//1.先将数据入到堆的最后一个位置
hp->_a[hp->_size] = x;
hp->_size++;
//2.向上调堆一次
AdjustUp(hp->_a, hp->_size, hp->_size - 1);
}
//弹出堆顶的数据
void HeapPop(Heap* hp)
{
assert(hp);
//1.交换第一个数据和最后一个数据
Swap(&hp->_a[0], &hp->_a[hp->_size - 1]);
//2.size减1(下标向前移动)
hp->_size --;
//3.向下调堆一次(因为堆顶的元素已变,但是左右子树都是一个堆)
AdjustDown(hp->_a, hp->_size, 0);
}
//取堆顶数据
HTDataType HeapTop(Heap* hp)
{
assert(hp);
return hp->_a[0];
}
//堆的大小
int HeapSize(Heap* hp)
{
assert(hp);
return hp->_size;
}
//空返回0,非空返回1
int HeapEmpty(Heap* hp)
{
assert(hp);
return hp->_size == 0 ? 0 : 1;
}
//堆排序
void HeapSort(HTDataType* a, int n)
{
assert(a);
int index = n;
for (int i = (n - 2) / 2; i >= 0; i--)
{
AdjustDown(a, n, i);
}
while (index != 1)
{
Swap(&a[0], &a[index - 1]);
index--;
AdjustDown(a, index, 0);
}
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
//打印堆的元素
void PrintHeap(Heap* hp)
{
assert(hp);
for (int i = 0; i < hp->_size; i++)
{
printf("%d ", hp->_a[i]);
}
printf("\n");
}
4.测试函数
#include "Heap.h"
void TestHeap()
{
Heap h;
HTDataType arr[] = { 17, 18, 68, 28, 54, 87 };
int size = sizeof(arr) / sizeof(arr[0]);
HeapSort(arr, size);
HeapInit(&h, arr, size);
PrintHeap(&h);
HeapPush(&h, 100);
PrintHeap(&h);
HeapPop(&h);
PrintHeap(&h);
printf("堆的大小为:%d\n", HeapSize(&h));
printf("?空(空:0,非空:1):%d\n", HeapEmpty(&h));
printf("堆顶元素为:%d\n", HeapTop(&h));
HeapDestory(&h);
}
int main()
{
TestHeap();
system("pause");
return 0;
}