堆的实现:
#include <malloc.h>
#include <assert.h>
typedef int DataType;
//函数指针--创建大堆或小堆
typedef int (*Comapra)(DataType,DataType);
typedef struct heap
{
DataType *_array;
int _size;
int _capycity;
Comapra _com;
}heap;
- 实现堆的以下接口:
// 创建堆
void create_hp(heap* head,int arr[],int size)
{
DataType* tmp=NULL;
int i=0;
if(NULL==head)
return;
//申请空间
checkcapycity(head,size);
//赋值
for(;i<size;i++)
{
head->_array[i]=arr[i];
}
head->_size=size;
//堆调整
i=(size-2)>>1; //找到最后一个非叶节点的下标
for (;i>=0;i--)
{
_adjust_up(head->_array,i,size,head->_com);
}
}
// 在堆中插入值为data的元素
void insert_heap(heap* head,DataType data)
{
int i=0;
int size;
if(NULL == head)
return;
size=++head->_size;
checkcapycity(head,size);
head->_array[size-1]=data;
i=((size-2)>>1); //找到最后一个非叶节点的下标
for (;i>=0;i--)
{
_adjust_up(head->_array,i,size,head->_com);
}
}
// 获取堆顶元素
DataType top_heap(heap* head)
{
assert(head);
return head->_array[0];
}
// 检测一个堆是否为空堆
int IsHeap_Empty(heap* head)
{
if(NULL==head)
return 0;
return 0==head->_size;
}
// 获取堆中元素的个数
int Heap_size(heap* head)
{
assert(head);
return head->_size;
}
// 删除堆顶元素
void delet_heap(heap* head)
{
int i;
int size=head->_size;
if(NULL == head)
return;
//用最后一个元素替换堆顶
head->_array[0]=head->_array[size-1];
head->_size--;
//堆调整
i=(size-2)>>1; //找到最后一个非叶节点的下标
for (;i>=0;i--)
{
_adjust_up(head->_array,i,size,head->_com);
}
}
// 销毁堆
void destroy_heap(heap* head)
{
assert(head);
head->_size=0;
head->_capycity=0;
free(head->_array);
head->_array=NULL;
}
对堆进行优化,一份代码既可以创建最大堆也可以创建最小堆
// 用于元素比较的比较器
//创小堆
int less(DataType a1,DataType a2)
{
return a1>a2?1:0;
}
//创大堆
int greater(DataType a1,DataType a2)
{
return a1<a2?1:0;
}
堆的应用之优先级队列,用堆封装优先级队列
#include "priorityQueue.h"
//初始化
void Init_priQueue(priQueue* head)
{
Init_heap(&(head->hp),head->hp._com);
}
//创建优先级队列
void create_priQueue(priQueue* head,int arr[],int size)
{
create_hp(&(head->hp),arr,size);
}
//插入元素
{
insert_heap(&(head->hp),data);
}
//删除优先级最高的元素
{
delet_heap(&(head->hp));
}
//获取优先级最高的元素
{
return top_heap(&(head->hp));
}
//销毁优先级队列
{
destroy_heap(&(head->hp));
}
//获取队列的size
{
assert(head);
return head->hp._size;
}
// 检测优先级队列是否为空
{
assert(head);
return 0==head->hp._size;
}
用堆的思想实现堆排序,给出代码实现
//堆排序
//升序--大堆
//降序--小堆
void heap_sort(int arr[],int size,Comapra com)
{
heap Hp;
int i=size;
int j=0;
Init_heap(&Hp,com);
create_hp(&Hp,arr,size);
for (;i>0;i--)
{
swap(&(Hp._array[0]),&(Hp._array[i-1]));
//堆调整
size--; //每交换一次,将最后一个元素“屏蔽”
j=(size-2)>>1; //找到最后一个非叶节点的下标
for (;j>=0;j--)
{
_adjust_up(Hp._array,j,size,com);
}
}
}
//交换
void swap(DataType* arr1,DataType* arr2)
{
DataType tmp=*arr1;
*arr1=*arr2;
*arr2=tmp;
}
//堆调整--向上
void _adjust_up(DataType* arr,int n,int size,Comapra com)
{
int parent=n;
int child=2*n+1;
while (child)
{
//找左右孩子中较大或较小的下标--child
if(((child+1)<size) && com(arr[child],arr[child+1]))
child+=1;
//交换节点
if(com(arr[parent],arr[child]))
swap(&(arr[parent]),&(arr[child]));
child=parent;
parent=((parent-1)>>1);
}
}
用堆解决top-K问题,给出代码实现
//top-k问题
//需创建小堆
void heap_top_k(int arr[],int k,int size)
{
heap Hp1;
int i=0;
Init_heap(&Hp1,less);
//先将数组的前k个元素入堆
create_hp(&Hp1,arr,k);
//将N-K个元素与堆顶比较
while (k<size)
{
int top=top_heap(&Hp1);
//如果比堆顶大,就入堆--插入
if(arr[k]>top)
{
delet_heap(&Hp1);
insert_heap(&Hp1,arr[k]);
}
k++;
}
//打印
for(;i<Hp1._size;i++)
{
printf("%d ",Hp1._array[i]);
}
printf("\n");
}