二叉堆也就是一棵完全二叉树。堆顶最大则为大根堆,堆顶最小则为小根堆,这里实现的是小根堆。
1.定义
用一个数组来存储数据,size代表当前堆的元素个数,capacity代表这个堆的总长度。
typedef int eletype;
typedef struct heapstruct
{
int capacity;
int size;
eletype *arr;
}Heap;
2.新建一个二叉堆
给二叉堆分配空间,给存储数据用的数组分配空间,每次分配空间都有可能分配失败,所以需要一个特判,分配失败就退出,然后将capacity设为max,因为还没有插入过,所以size刚开始为0。
Heap *CreateHeap(int max)
{
Heap *H;
H = malloc(sizeof(Heap));
if (H == NULL) {
printf("Out of space\n");
return NULL;
}
H->arr = malloc(sizeof(eletype) * (max + 1));
if (H->arr == NULL) {
printf("Out of space\n");
return NULL;
}
H->capacity = max;
H->size = 0;
H->arr[0] = 0;
return H;
}
3.插入
写一个函数,percolateUP用来找到合适位置,意思是上滤找到合适的插入位置,然后将size+1代表元素数量增加了1个,然后在最开头需要进行一个特判,如果这个堆满了,代表无法在进行插入了,所以要返回失败。
int isFull(Heap h){
return h->capacity==h->size;
}
void percolateUP(int k,Heap h){
int x;
x=h->arr[k];
int i;
for(i=k;i>1&&h->arr[i]<h->arr[i/2];i/=2) h->arr[i]=h->arr[i/2];
h->arr[i]=x;
}
int insertHeap(int x,Heap h){
if(isFull(h)) return 0;
h->arr[(h->size+1)]=x;
h->size++;
percolateUP(h->size,h);
return 1;
}
4.删除最小元素(堆顶)
为了保证删除后仍是一个完整的二叉堆,要将原堆顶以下的数据进行适当的上滤,和插入差不多,将size--,代表元素数量减1(毕竟删除了一个数字)。
eletype DeleteMin(Heap *H)
{
if (H->size == 0) {
printf("Heap is empty\n");
return 0;
}
eletype min = H->arr[1];
eletype last = H->arr[H->size--];
int i, child;
for(i = 1; i * 2 <= H->size; i = child) {
child = i * 2;
if (child != H->size && H->arr[child + 1] < H->arr[child])
child++;
if (last > H->arr[child])
H->arr[i] = H->arr[child];
else
break;
}
H->arr[i] = last;
return min;
}
5、判断堆是否为空
看他的元素个数是否为0
int isEmpty(Heap *H)
{
if (H->size == 0) {
printf("Heap is empty\n");
return 0;
}
}
6、判断堆是否满了
就看size和capacity是否相等
int isFull(Heap h){
return h->capacity==h->size;
}
7、输出堆
按顺序输出即可
void printHeap(Heap h){
for(int i=1;i<=h->capacity;i++)
cout<<h->arr[i]<<" ";
}
堆的基本操作就讲到这里了,希望大家尽快学会哦!
总代码:
#include<bits/stdc++.h>
using namespace std;
typedef int Elem;
struct heap{
Elem *data;
int capacity;
int size;
};
typedef struct heap* Heap;
Heap initHeap(int max){
Heap h;
h=(Heap)malloc(sizeof(struct heap));
if(!h) return NULL;
h->data=(Elem*)malloc(sizeof(Elem)*(max+1));
if(!h->data) return NULL;
h->capacity=max;
h->size=0;
for(int i=1;i<=max;i++) h->data[i]=0;
return h;
}
void printHeap(Heap h){
for(int i=1;i<=h->capacity;i++) cout<<h->data[i]<<" ";
}
int isEmpty(Heap h){
return h->size==0;
}
int isFull(Heap h){
return h->capacity==h->size;
}
void percolateUP(int k,Heap h){
Elem x;
x=h->data[k];
int i;
for(i=k;i>1&&h->data[i]<h->data[i/2];i/=2) h->data[i]=h->data[i/2];
h->data[i]=x;
}
int insertHeap(Elem x,Heap h){
if(isFull(h)) return 0;
h->data[(h->size+1)]=x;
h->size++;
percolateUP(h->size,h);
return 1;
}
void percolateDown(int k,Heap h){
Elem x;
x=h->data[k];
int i,child;
for(i=k;i*2<=h->size;i=child){
child=i*2;
if(child!=h->size&&h->data[child]>h->data[child+1]) child++;
if(h->data[i]>h->data[child]) h->data[i]=h->data[child];
}
h->data[i]=x;
}
int removeHeap(Elem *px,Heap h){
if(isEmpty(h)) return 0;
*px=h->data[1];
h->data[1]=h->data[h->size];
h->size--;
percolateDown(1,h);
return 1;
}
int main(){
Heap h;
int n;
cin>>n;
h=initHeap(10);
int a[n];
for(int i=0;i<n;i++){
cin>>a[i];
insertHeap(a[i],h);
}
printHeap(h);
cout<<endl;
while(1){
int f;
cout<<"1代表插入,0代表删除:";
cin>>f;
if(f==1){
int t;
cout<<"请输入要插入的数字:";
cin>>t;
insertHeap(t,h);
}
else if(f==0){
int t;
removeHeap(&t,h);
cout<<"删除的数为:"<<t<<endl;
}
else{
cout<<"没有此命令!"<<endl;
continue;
}
printHeap(h);
}
return 0;
}