一、定义
堆(Heap)是计算机科学中一类特殊的数据结构,是最高效的优先级队列。堆通常是一个可以被看做一棵完全二叉树的数组对象。
二、常用分类
二叉堆:二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。
最大堆(大顶堆):除根节点外的任何结点的数据均不大于其父节点数据。
最小堆(小顶堆):除根节点外的任何结点的数据均不小于其父节点数据。
二项堆:二项堆是是二项树的集合或是由一组二项树组成。二项堆具有良好的性质。在O(log2n)
的时间内即可完成两个二项堆合并操作,所以二项堆是可合并堆,而仅仅需要O(1) 的时间,二项堆即可完成插入操作。因此,基于二项堆实现的优先队列和进程调度算法有着很好的时间性能。同时由于二项树的结构特性和性质,二项树在网络优化等诸多领域也应用广泛。
二项树:二项树是一种递归定义的有序树,二项树递归定义如下:
1、度数为0的二项树只包含一个结点。
2、度数为k的二项树有一个根结点,根结点下有k 个子女,每个子女分别是度数分别为k-1、
k-2...0 的二项树的根。
斐波那契堆是二项堆的一种(目前还不懂)
三、基本操作(最大堆为例)
1、MaxHeap *creatHeap(); //创建堆
2、 void insertHeap(MaxHeap *pHeap,Elementtype value);
//插入函数:堆不满的情况下,将数据插入至数组的末尾,父节点为当前节点的1/2,自下而上比较大小,当大于父节点的值,父节点下移,直至插入值小于父节点数值停止。插入数据。
3、Elementtype delHeap(MaxHeap *pHeap);
//删除函数:删除根节点数据将根的末位数据复制到根节点,然后逐一和子结点中较大值比较,小于子结点较大值时,交换;直至均大于两个子结点的值。
4、 int isfullHeap(MaxHeap *pHeap); //判别堆满
5、 int isemptyHeap(MaxHeap *pHeap); //判别堆空
四、代码如下(一般用数组实现)
heap.h↓↓↓
#ifndef HEAP_H
#define HEAP_H
#include <stdio.h>
#include <stdlib.h>
#define MAXsize 1000 //设置堆的最大容量
#define MAXdata 1000 //设置哨兵值
typedef struct heap MaxHeap;
typedef int Elementtype;
struct heap{
Elementtype *data;
int size;
};
MaxHeap *creatHeap(); //创建堆
void insertHeap(MaxHeap *pHeap,Elementtype value); //插入函数
Elementtype delHeap(MaxHeap *pHeap); //删除函数
int isfullHeap(MaxHeap *pHeap); //判别堆满
#endif
heap.c↓↓↓
#include "heap.h"
//typedef struct heap MaxHeap;
//typedef int Elementtype;
//struct heap{
// Elementtype *data;
// int size;
//};
//#define MAXsize 1000
//#define MAXdata 1000
MaxHeap *creatHeap(){ //创建堆
MaxHeap *pHeap=(MaxHeap*)malloc(sizeof(MaxHeap));
pHeap->data=(Elementtype*)malloc((MAXsize+1)*sizeof(Elementtype));
pHeap->size=0;
pHeap->data[0]=MAXdata; //设置哨兵
return pHeap;
}
void insertHeap(MaxHeap *pHeap,Elementtype value){ //插入函数
int cnt=0;
if(!isfullHeap(pHeap)){
pHeap->data[++(pHeap->size)]=value;
cnt=pHeap->size;
while(value>pHeap->data[cnt/2]){ //设置哨兵后可不用判断cnt出界
pHeap->data[cnt]=pHeap->data[cnt/2];
cnt/=2;
}
if(cnt) pHeap->data[cnt]=value;
}
}
Elementtype delHeap(MaxHeap *pHeap){ //删除函数
int parent=1,child=2*parent;
Elementtype resalt=pHeap->data[1];
Elementtype temp=pHeap->data[pHeap->size--];
for(parent=1;parent*2<=pHeap->size;parent=child){
child=parent*2;
if(child!=pHeap->size&&pHeap->data[child]<pHeap->data[child+1])
//当左孩子节点不是最后一个元素,且父节点小于右孩子节点,child指向右孩子节点,取得两个子结点中较大值
child++;
if(temp<pHeap->data[child]){//父节点小于子结点中较大值,该子结点上移,parent下移
pHeap->data[parent]=pHeap->data[child];
parent=child;
}else{//大于等于较大值时,跳出循环
break;
}
}
pHeap->data[parent]=temp;//将数据插入当前parent指向的位置
return resalt;
}
int isfullHeap(MaxHeap *pHeap){ //判别堆满
return pHeap->size==MAXsize;
}
int isemptyHeap(MaxHeap *pHeap){ //判别堆空
return pHeap->size==0;
}
main.c↓↓↓
#include <stdio.h>
#include <stdlib.h>
#include "heap.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
//typedef struct heap MaxHeap;
//typedef int Elementtype;
//struct heap{
// Elementtype *data;
// int size;
//};
//#define MAXsize 1000
//#define MAXdata 1000
int main(int argc, char *argv[]) {
MaxHeap * pHeap=creatHeap();
for(int i=0;i<10;i++)
insertHeap(pHeap,i);
for(int i=0;i<10;i++){
printf("%d ",delHeap(pHeap));
}
return 0;
}