目录
D.堆的判空 Heapempty 堆顶数据 Heaptop 堆的大小 Heapsize
一.堆的概念及结构
二.接口实现
A.初始化 Heapinit 销毁 Heapdestroy
B.插入 Heappush 向上调整 AdjustUp
1.Heappush
2.AdjustUp
void Swap(HPdatatype* p1, HPdatatype* p2) //交换函数
{
HPdatatype tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
void AdjustUp(HPdatatype* arr, int child) //向上调整
{
assert(arr);
int parent = (child - 1) / 2;
while (child > 0)
{
if (arr[child] > arr[parent])
{
Swap(&arr[child], &arr[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
break;
}
}
void Heappush(Heap* php, HPdatatype x)
{
assert(php);
if (php->size == php->capacity)
{
HPdatatype* tmp = (HPdatatype*)realloc(php->arr, 2 * sizeof(HPdatatype) * php->capacity);
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
php->arr = tmp;
php->capacity *= 2;
}
php->arr[php->size] = x;
php->size++;
AdjustUp(php->arr, php->size - 1); //注意这里要传size-1,因为size表示的是下一个位置
}
C.删除 Heappop 向下调整 AdjustDown
D.堆的判空 Heapempty 堆顶数据 Heaptop 堆的大小 Heapsize
三.源码
Heap.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <time.h>
#define MAX_MIN < //通过改变这里的符号,可以决定是建大堆还是小堆
typedef int HPdatatype;
typedef struct Heap
{
HPdatatype* arr;
int size;
int capacity;
}Heap;
void Heapinit(Heap* php);
void Swap(HPdatatype* p1, HPdatatype* p2);
void AdjustUp(HPdatatype* arr, int child); //向上调整
void Heappush(Heap* php, HPdatatype x);
void AdjustDown(HPdatatype* arr, int parent, int n); //向下调整
void Heappop(Heap* php);
HPdatatype Heaptop(Heap* php);
int Heapsize(Heap* php);
bool Heapempty(Heap* php);
void Heapdestroy(Heap* php);
Heap.c
#include "Heap.h"
void Heapinit(Heap* php)
{
assert(php);
php->arr = (HPdatatype*)malloc(sizeof(HPdatatype) * 4);
if (php->arr == NULL)
{
perror("malloc fail");
exit(-1);
}
php->size = 0;
php->capacity = 4;
}
void Swap(HPdatatype* p1, HPdatatype* p2)
{
HPdatatype tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
///С
void AdjustUp(HPdatatype* arr, int child)
{
assert(arr);
int parent = (child - 1) / 2;
while (child > 0)
{
if (arr[child] MAX_MIN arr[parent])
{
Swap(&arr[child], &arr[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
break;
}
}
void Heappush(Heap* php, HPdatatype x)
{
assert(php);
if (php->size == php->capacity) //插入前,判断数组是否已满
{
HPdatatype* tmp = (HPdatatype*)realloc(php->arr, 2 * sizeof(HPdatatype) * php->capacity);
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
php->arr = tmp;
php->capacity *= 2;
}
php->arr[php->size] = x;
php->size++;
AdjustUp(php->arr, php->size - 1); //这里要传size-1
}
void AdjustDown(HPdatatype* arr, int parent, int n)
{
assert(arr);
int child = 2 * parent + 1;
while (child < n)
{
//判断较大(较小)的子节点
if ((child + 1) < n && arr[child + 1] MAX_MIN arr[child])
{
child++;
}
if (arr[child] MAX_MIN arr[parent])
{
Swap(&arr[child], &arr[parent]);
parent = child;
child = 2 * parent + 1;
}
else
break;
}
}
void Heappop(Heap* php)
{
assert(php);
assert(php->size);
Swap(&php->arr[0], &php->arr[php->size - 1]);
php->size--;
AdjustDown(php->arr, 0, php->size);
}
HPdatatype Heaptop(Heap* php)
{
assert(php);
assert(php->size); //为空时不能取数据
return php->arr[0];
}
int Heapsize(Heap* php)
{
assert(php);
return php->size;
}
bool Heapempty(Heap* php)
{
assert(php);
return php->size == 0; //size==0即为空
}
void Heapdestroy(Heap* php)
{
assert(php);
free(php->arr);
php->arr = NULL;
php->size = 0;
php->capacity = 0;
}
test.c
#include "Heap.h"
void testHeap()
{
Heap hp;
Heapinit(&hp);
int i = 0, n = 10;
int x = 0;
while (n)
{
x = rand() % 100 + 1;
Heappush(&hp, x);
n--;
}
while (!Heapempty(&hp))
{
printf("%d ", Heaptop(&hp));
Heappop(&hp);
}
printf("\n");
Heapdestroy(&hp);
}
int main()
{
srand((unsigned int)time(NULL));
testHeap();
return 0;
}