最小堆和最大堆的原理是一样的,学会其中一个另一个自然也会了。
接下来我们以最小堆为例:
堆的抽象模型就是二叉树,最小堆的意思是任一个节点的值都比此节点的子节点的值要小。
例子
1 | 2 | 3 | 7 | 9 | 8 | 10 |
上述数组所表示的堆是如下:
c++代码实现
#include <bits/stdc++.h>
using namespace std;
typedef struct minHeap
{
int *arr;//存储堆的数组指针
int size;//元素的数目
int cap;//堆的容量
}MinHeap;
MinHeap *createMinHeap(int cap)
{
MinHeap *h = new MinHeap;
h->arr = new int[cap];
h->cap = cap;
h->size = 0;
return h;
}
void swap(int *a,int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
//往堆中插值
void insertKey(MinHeap *h,int key)
{
if(h->size == h->cap)
{
cout << "堆已满" << endl;
return;
}
h->size++;
int i = h->size-1;
h->arr[i] = key;
//(i-1)/2 是 索引为i的节点的父节点的索引
while(i != 0 && h->arr[(i-1)/2] > h->arr[i])
{
swap(&h->arr[i],&h->arr[(i-1)/2]);
i = (i-1)/2;
}
}
//将索引为i的值减小为new_key
void decreaseKey(MinHeap *h,int i,int new_key)
{
if(i > h->size-1)
return;
h->arr[i] = new_key;
while(i != 0 && h->arr[(i-1)/2] > h->arr[i])
{
swap(&h->arr[i],&h->arr[(i-1)/2]);
i = (i-1)/2;
}
}
void MinHeapify(MinHeap *h,int index)
{
int l = 2*index+1;//左节点的索引
int r = 2*index+2;//右节点的索引
int smallest = index;
if(h->arr[smallest] > h->arr[l] && l < h->size)
smallest = l;
if(h->arr[smallest] > h->arr[r] && r < h->size)
smallest = r;
if(smallest != index)
{
swap(&h->arr[index],&h->arr[smallest]);
MinHeapify(h,smallest);
}
}
//获取最小值,并删除
int extractMin(MinHeap *h)
{
if(h->size <= 0)
return INT_MAX;
if(h->size == 1)
{
h->size--;
return h->arr[0];
}
int min = h->arr[0];
h->arr[0] = h->arr[h->size-1];
h->size--;
MinHeapify(h,0);
return min;
}
//获取最小值
int getMin(MinHeap *h)
{
return h->arr[0];
}
int main(void)
{
MinHeap *h = createMinHeap(7);
insertKey(h,1);
insertKey(h,2);
insertKey(h,3);
insertKey(h,7);
insertKey(h,9);
insertKey(h,8);
insertKey(h,10);
cout << extractMin(h) <<endl;
cout << getMin(h) <<endl;
decreaseKey(h,2, 0);
cout << getMin(h)<< endl;;
return 0;
}