今天,我带来堆的代码实现总结。
目录
堆的三个实现文档
Heap.h --------头文件的引用和函数的声明
Heap.c --------函数的定义
test.c -------- 堆的代码实现的检验
初始化函数
//初始化函数
void InitHeap(Heap* ps)
{
assert(ps);
ps->Data = NULL;
ps->size = ps->capacity = 0;
}
销毁函数
//销毁函数
void DestroyHeap(Heap* ps)
{
assert(ps);
free(ps->Data);
ps->Data = NULL;
ps->size = ps->capacity = 0;
}
插入函数
//插入函数
void HeapPush(Heap* ps, HeapDataType x)
{
assert(ps);
if (ps->size == ps->capacity)
{
int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
HeapDataType* tmp = (HeapDataType*)realloc(ps->Data,sizeof(HeapDataType) * NewCapacity);
if (tmp == NULL)
{
perror("malloc fail");
exit(1);
}
ps->Data = tmp;
ps->capacity = NewCapacity;
}
ps->Data[ps->size] = x;
ps->size++;
AdjustUp(ps,ps->size-1);
}
删除堆顶的函数
//删除堆顶的元素
void HeapPop(Heap* ps)
{
assert(ps);
assert(ps->size > 0);
Swap(&ps->Data[0],&ps->Data[ps->size-1]);
ps->size--;
AdjustDown(ps,ps->size,0);
}
向上调整函数
//向上调整的函数
void AdjustUp(Heap* ps, int child)
{
assert(ps);
HeapDataType parent = (child - 1) / 2;
while (child > 0)
{
if (ps->Data[child] > ps->Data[parent])
{
Swap(&ps->Data[child],&ps->Data[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
向下调整函数
//向下调整函数
void AdjustDown(Heap* ps, int n, int parent)
{
assert(ps);
HeapDataType child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n && ps->Data[child + 1] > ps->Data[child])
{
child++;
}
if (ps->Data[child] > ps->Data[parent])
{
Swap(&ps->Data[child],&ps->Data[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
判断是否为空的函数
//判断是堆是否为空的函数
bool HeapEmpty(Heap* ps)
{
assert(ps);
return ps->size == 0;
}
统计堆的元素个数
//统计堆的元素个数
int HeapSize(Heap* ps)
{
assert(ps);
return ps->size;
}
取出堆顶的元素
//取出堆顶的元素
HeapDataType HeapTop(Heap* ps)
{
assert(ps);
assert(ps->size > 0);
return ps->Data[0];
}
利用数组开辟堆的函数
//利用数组元素开辟堆
void CreatHeap(Heap* ps, HeapDataType* data, int n)
{
assert(ps);
ps->Data = (HeapDataType*)malloc(sizeof(HeapDataType) * n);
if (ps->Data == NULL)
{
perror("malloc fail");
exit(1);
}
memcpy(ps->Data,data,sizeof(HeapDataType) * n);
ps->size = ps->capacity = n;
//建堆算法
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(ps,n,i);
}
}
交换函数
//交换函数
void Swap(HeapDataType* left, HeapDataType* right)
{
HeapDataType tmp = *left;
*left = *right;
*right = tmp;
}
打印函数
//打印函数
void HeapPrint(Heap* ps)
{
assert(ps);
for (int i = 0; i < ps->size; i++)
{
printf("%d ",ps->Data[i]);
}
printf("\n");
}
头文件的引用和函数的声明
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<assert.h>
typedef int HeapDataType;
typedef struct Heap
{
HeapDataType* Data;
int size;
int capacity;
}Heap;
//初始化函数
void InitHeap(Heap* ps);
//销毁函数
void DestroyHeap(Heap* ps);
//插入函数
void HeapPush(Heap* ps, HeapDataType x);
//删除堆顶的元素
void HeapPop(Heap* ps);
//向上调整的函数
void AdjustUp(Heap* ps, int child);
//向下调整函数
void AdjustDown(Heap* ps, int n, int parent);
//判断是堆是否为空的函数
bool HeapEmpty(Heap* ps);
//统计堆的元素个数
int HeapSize(Heap* ps);
//取出堆顶的元素
HeapDataType HeapTop(Heap* ps);
//利用数组元素开辟堆
void CreatHeap(Heap* ps, HeapDataType* data, int n);
//交换函数
void Swap(HeapDataType* left, HeapDataType* right);
//打印函数
void HeapPrint(Heap* ps);
菜单的实现和函数的调用
#include "Heap.h"
#define Max 100
void menu()
{
printf("***********************************************************************\n");
printf("******** 1.利用数组元素开辟堆 2.插入 ************\n");
printf("******** 3.删除堆顶的元素 4.统计堆的元素个数 ************\n");
printf("******** 5.取出堆顶的元素 6.判断是堆是否为空 ************\n");
printf("******** 7.打印 0.退出 ************\n");
printf("***********************************************************************\n");
}
int main()
{
int input = 0;
int N = 0;
HeapDataType Num = 0;
Heap HP;
InitHeap(&HP);
HeapDataType data[Max];
do
{
menu();
printf("请选择:>\n");
scanf("%d",&input);
switch(input)
{
case 1:
printf("请输入数组的元素个数:>");
scanf("%d",&N);
printf("请输入N个元素,中间用空格隔开:>");
for (int i = 0; i < N; i++)
{
scanf("%d",&data[i]);
}
CreatHeap(&HP,data,N);
break;
case 2:
printf("请输入想要插入的数:\n");
scanf("%d",&Num);
HeapPush(&HP,Num);
break;
case 3:
HeapPop(&HP);
break;
case 4:
printf("%d\n", HeapSize(&HP));
break;
case 5:
printf("%d\n", HeapTop(&HP));
break;
case 6:
if (true == HeapEmpty(&HP))
printf("堆为空\n");
else
printf("堆非空\n");
break;
case 7:
HeapPrint(&HP);
break;
case 0:
printf("退出\n");
HeapEmpty(&HP);
break;
}
} while (input);
return 0;
}
Heap.h文档的代码实现
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<assert.h>
typedef int HeapDataType;
typedef struct Heap
{
HeapDataType* Data;
int size;
int capacity;
}Heap;
//初始化函数
void InitHeap(Heap* ps);
//销毁函数
void DestroyHeap(Heap* ps);
//插入函数
void HeapPush(Heap* ps, HeapDataType x);
//删除堆顶的元素
void HeapPop(Heap* ps);
//向上调整的函数
void AdjustUp(Heap* ps, int child);
//向下调整函数
void AdjustDown(Heap* ps, int n, int parent);
//判断是堆是否为空的函数
bool HeapEmpty(Heap* ps);
//统计堆的元素个数
int HeapSize(Heap* ps);
//取出堆顶的元素
HeapDataType HeapTop(Heap* ps);
//利用数组元素开辟堆
void CreatHeap(Heap* ps, HeapDataType* data, int n);
//交换函数
void Swap(HeapDataType* left, HeapDataType* right);
//打印函数
void HeapPrint(Heap* ps);
Heap.c文档的代码实现
#include "Heap.h"
//初始化函数
void InitHeap(Heap* ps)
{
assert(ps);
ps->Data = NULL;
ps->size = ps->capacity = 0;
}
//销毁函数
void DestroyHeap(Heap* ps)
{
assert(ps);
free(ps->Data);
ps->Data = NULL;
ps->size = ps->capacity = 0;
}
//插入函数
void HeapPush(Heap* ps, HeapDataType x)
{
assert(ps);
if (ps->size == ps->capacity)
{
int NewCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
HeapDataType* tmp = (HeapDataType*)realloc(ps->Data,sizeof(HeapDataType) * NewCapacity);
if (tmp == NULL)
{
perror("malloc fail");
exit(1);
}
ps->Data = tmp;
ps->capacity = NewCapacity;
}
ps->Data[ps->size] = x;
ps->size++;
AdjustUp(ps,ps->size-1);
}
//删除堆顶的元素
void HeapPop(Heap* ps)
{
assert(ps);
assert(ps->size > 0);
Swap(&ps->Data[0],&ps->Data[ps->size-1]);
ps->size--;
AdjustDown(ps,ps->size,0);
}
//向上调整的函数
void AdjustUp(Heap* ps, int child)
{
assert(ps);
HeapDataType parent = (child - 1) / 2;
while (child > 0)
{
if (ps->Data[child] > ps->Data[parent])
{
Swap(&ps->Data[child],&ps->Data[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
//向下调整函数
void AdjustDown(Heap* ps, int n, int parent)
{
assert(ps);
HeapDataType child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n && ps->Data[child + 1] > ps->Data[child])
{
child++;
}
if (ps->Data[child] > ps->Data[parent])
{
Swap(&ps->Data[child],&ps->Data[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
//判断是堆是否为空的函数
bool HeapEmpty(Heap* ps)
{
assert(ps);
return ps->size == 0;
}
//统计堆的元素个数
int HeapSize(Heap* ps)
{
assert(ps);
return ps->size;
}
//取出堆顶的元素
HeapDataType HeapTop(Heap* ps)
{
assert(ps);
assert(ps->size > 0);
return ps->Data[0];
}
//利用数组元素开辟堆
void CreatHeap(Heap* ps, HeapDataType* data, int n)
{
assert(ps);
ps->Data = (HeapDataType*)malloc(sizeof(HeapDataType) * n);
if (ps->Data == NULL)
{
perror("malloc fail");
exit(1);
}
memcpy(ps->Data,data,sizeof(HeapDataType) * n);
ps->size = ps->capacity = n;
//建堆算法
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(ps,n,i);
}
}
//交换函数
void Swap(HeapDataType* left, HeapDataType* right)
{
HeapDataType tmp = *left;
*left = *right;
*right = tmp;
}
//打印函数
void HeapPrint(Heap* ps)
{
assert(ps);
for (int i = 0; i < ps->size; i++)
{
printf("%d ",ps->Data[i]);
}
printf("\n");
}
test.c文档的代码实现
#include "Heap.h"
#define Max 100
void menu()
{
printf("***********************************************************************\n");
printf("******** 1.利用数组元素开辟堆 2.插入 ************\n");
printf("******** 3.删除堆顶的元素 4.统计堆的元素个数 ************\n");
printf("******** 5.取出堆顶的元素 6.判断是堆是否为空 ************\n");
printf("******** 7.打印 0.退出 ************\n");
printf("***********************************************************************\n");
}
int main()
{
int input = 0;
int N = 0;
HeapDataType Num = 0;
Heap HP;
InitHeap(&HP);
HeapDataType data[Max];
do
{
menu();
printf("请选择:>\n");
scanf("%d",&input);
switch(input)
{
case 1:
printf("请输入数组的元素个数:>");
scanf("%d",&N);
printf("请输入N个元素,中间用空格隔开:>");
for (int i = 0; i < N; i++)
{
scanf("%d",&data[i]);
}
CreatHeap(&HP,data,N);
break;
case 2:
printf("请输入想要插入的数:\n");
scanf("%d",&Num);
HeapPush(&HP,Num);
break;
case 3:
HeapPop(&HP);
break;
case 4:
printf("%d\n", HeapSize(&HP));
break;
case 5:
printf("%d\n", HeapTop(&HP));
break;
case 6:
if (true == HeapEmpty(&HP))
printf("堆为空\n");
else
printf("堆非空\n");
break;
case 7:
HeapPrint(&HP);
break;
case 0:
printf("退出\n");
HeapEmpty(&HP);
break;
}
} while (input);
return 0;
}
今天,堆的代码实现总结就讲到这里,关注点一点,下期更精彩。