堆的概念:如果有一个关键码的集合k = {k0 , k1 , k2 , … , kn-1},把他的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:ki <= k2*i + 1 且 ki <= k2*i + 2(ki >= k2*i + 1且 ki >= k2*i + 2) i = 0 , 1, 2, 3, 4…,则称为小堆(或大堆).
例如下图:
下面用到了函数指针,在这里对函数指针进行粗略的描述
void Init(int a); //这个为一个函数. Init 为函数名
void ( * )(int a); // 这个是一种函数指针类型 就和 int * , char * 一样
void (* Init)(int a); // Init为函数指针
typedef void (* Init) (int a);// Init为一种类型(函数指针类型) 就像是 typedef int* p ; 这里的 Init 与 p 的意思是一样的
将二叉树调整为最小堆的原理:
void AdjustDown(Heap* hp, int Parent)//调整顺序
{
int childe = (Parent << 1) + 1;
while (childe < hp->_size)
{
if (childe + 1 < hp->_size&& hp->_compare(hp->_hp[childe+1] , hp->_hp[childe]))
{
childe += 1;
}
if (hp->_compare(hp->_hp[childe] , hp->_hp[Parent]))
{
Swap(&hp->_hp[childe], &hp->_hp[Parent]);
Parent = childe;
childe = (Parent << 1) + 1;
}
else
return;
}
}
下面是关于堆的基本操作:
//Heap.h
#pragma once
#include
#include
#include
typedef int HPDataType;
typedef int (*PCompare)(HPDataType left, HPDataType right);//函数指针
typedef struct Heap
{
HPDataType* _hp;
int _capacity;
int _size;
PCompare _compare;
}Heap;
int Less(HPDataType left, HPDataType right);
int Greater(HPDataType left, HPDataType right);
void InitHeap(Heap* hp);//初始化
void CreatHeap(Heap* hp, int* array, int size,PCompare compare);//创建堆
void AdjustDown(Heap* hp, int Parent);//调整顺序
void InsertHeap(Heap* hp,HPDataType data);//插入
void RemoveHeap(Heap* hp);//删除
int SizeHeap(Heap* hp);//求大小
int EmptyHeap(Heap* hp);//判空
void DestroyHeap(Heap* hp);//销毁
HPDataType TopHeap(Heap* hp);//求堆顶元素
void Adjustup(Heap* hp, int child);
void CheckCapacity(Heap* hp);//扩容
//Heap.c
#include"Heap.h"
void InitHeap(Heap* hp)//初始化
{
hp->_hp = (HPDataType*)malloc(3 * sizeof(HPDataType));
hp->_size = 0;
hp->_capacity = 3;
hp->_compare = NULL;
}
int Less(HPDataType left, HPDataType right)
{
return left < right;
}
int Greater(HPDataType left, HPDataType right)
{
return left > right;
}
void Swap(HPDataType** childe,HPDataType** parent)
{
HPDataType* tmp = *childe;
*childe = *parent;
*parent = tmp;
}
void AdjustDown(Heap* hp, int Parent)//调整顺序
{
int childe = (Parent << 1) + 1;
while (childe < hp->_size)
{
if (childe + 1 < hp->_size&& hp->_compare(hp->_hp[childe+1] , hp->_hp[childe]))
{
childe += 1;
}
if (hp->_compare(hp->_hp[childe] , hp->_hp[Parent]))
{
Swap(&hp->_hp[childe], &hp->_hp[Parent]);
Parent = childe;
childe = (Parent << 1) + 1;
}
else
return;
}
}
void CreatHeap(Heap* hp, int* array, int size, PCompare compare)//创建堆
{
int root;
assert(hp);
root = (size - 2) / 2;
hp->_hp = (HPDataType*)malloc(size * sizeof(HPDataType));
if (0 == hp->_hp)
{
perror("malloc::hp");
return;
}
hp->_capacity = size;
memcpy(hp->_hp, array, size * sizeof(HPDataType));
hp->_size = size;
hp->_compare = compare;
for (; root >= 0; root--)
{
AdjustDown(hp, root);
}
}
void CheckCapacity(Heap* hp)//扩充容量
{
assert(hp);
if (hp->_size == hp->_capacity)
{
int i = 0;
HPDataType* pTem = (HPDataType*)malloc((hp->_size * 2) * sizeof(HPDataType));
if (pTem == NULL)
{
perror("malloc::CheakCapacity");
return;
}
/*for (i = 0; i < hp->_size; i++)
{
pTem[i] = hp->_hp[i];
}*/
memcpy(pTem, hp->_hp, hp->_size * sizeof(HPDataType));
free(hp->_hp);
hp->_hp = pTem;
hp->_capacity = hp->_size * 2;
}
}
void Adjustup(Heap* hp, int child)//向上调整
{
int parent = ((child - 1) >> 1);
while (child)
{
if (hp->_compare(hp->_hp[child] , hp->_hp[parent]))
{
Swap(&hp->_hp[parent], &hp->_hp[child]);
child = parent;
parent = ((child - 1) >> 1);
}
else
return;
}
}
void InsertHeap(Heap* hp, HPDataType data)//插入
{
assert(hp);
//将元素先放到堆中
CheckCapacity(hp);
hp->_hp[hp->_size++] = data;
//对堆中元素进行调整(向上调整)
Adjustup(hp, hp->_size - 1);//向上调整
}
int SizeHeap(Heap* hp)//求大小
{
assert(hp);
return hp->_size;
}
int EmptyHeap(Heap* hp)//判空
{
assert(hp);
return !(hp->_size);
}
HPDataType TopHeap(Heap* hp)//求堆顶元素
{
assert(hp);
return hp->_hp[0];
}
void RemoveHeap(Heap* hp)//删除
{
assert(hp);
if (EmptyHeap(hp))
return;
Swap(&hp->_hp[0], &hp->_hp[hp->_size - 1]);
hp->_size--;
AdjustDown(hp, 0);
}
void DestroyHeap(Heap* hp)//销毁
{
assert(hp);
free(hp->_hp);
hp->_size = 0;
hp->_capacity = 0;
hp->_compare = NULL;
}
//test.c
#include"Heap.h"
void test1()
{
Heap hp;
int array[] = { 1,2,3,4,5,6,7,8,9 };
int size = sizeof(array) / sizeof(array[0]);
InitHeap(&hp);//初始化
CreatHeap(&hp, array,size,Greater);//创建堆
InsertHeap(&hp,0);//插入
RemoveHeap(&hp);//删除
}
int main()
{
test1();
system("pause");
return 0;
}