先贴代码,再讲述自己的理解
#include<iostream>
using namespace std;
#define defaultSize 30
class MinHeap{
private:
int *heap; //存储数据
int currentSize; //当前可存入数据的位置
int maxSize; //可存储的数据的个数
void FilterUp(int start);
void SiftDown(int start,int m);
public:
bool IsFull();
bool IsEmpty();
MinHeap(int heapSize=defaultSize);
void printHeap();
bool insert(int x);
bool removeMin(int& x);
int getSize();
void SortHeap();
};
cpp:
#include"MinHeap.h"
/************************************************************************/
/*
初始化对象
*/
/************************************************************************/
MinHeap::MinHeap(int heapSize/* =defaultSize */)
{
maxSize=heapSize;
currentSize=0;
heap=new int[maxSize];
}
/************************************************************************/
/*
判断是否为空堆
*/
/************************************************************************/
bool MinHeap::IsEmpty()
{
return (currentSize==0)?true:false;
}
/************************************************************************/
/*
判断堆是否已经满了
*/
/************************************************************************/
bool MinHeap::IsFull()
{
return (currentSize==maxSize)?true:false;
}
/************************************************************************/
/*
获取堆的大小
*/
/************************************************************************/
int MinHeap::getSize()
{
return currentSize-1;
}
/************************************************************************/
/*
从一个位置向上调整堆
*/
/************************************************************************/
void MinHeap::FilterUp(int start)
{
int j=start;
int i=(j-1)/2;
int temp=heap[j];
while(j>0)
{
if(temp>=heap[i]) //如果父亲节点小于等于子节点
{
break;
}
else
{
heap[j]=heap[i];
j=i;
i=(j-1)/2; //继续向上调整
}
}
heap[j]=temp;
}
/************************************************************************/
/*
从一个位置向下调整到M的位置
*/
/************************************************************************/
void MinHeap::SiftDown(int start,int m)
{
int i=start;
int j=i*2+1;
int temp=heap[i];
while(j<=m)
{
if(j<m&&heap[j]>heap[j+1]) //如果左孩子大于右孩子
{
j++;
}
if(temp<=heap[j])
{
break;
}
else
{
heap[i]=heap[j];
i=j;
j=i*2+1; //继续向下调整
}
}
heap[i]=temp;
}
/************************************************************************/
/*
插入一个新的节点 */
/************************************************************************/
bool MinHeap::insert(int x)
{
if(IsFull())
{
return false;
}
heap[currentSize]=x;
FilterUp(currentSize);
currentSize++;
return true;
}
/************************************************************************/
/*
去除堆的顶点,即最小的数据
*/
/************************************************************************/
bool MinHeap::removeMin(int& x)
{
if(IsEmpty())
{
return false;
}
x=heap[0];
heap[0]=heap[currentSize-1];
currentSize--;
SiftDown(0,currentSize-1);
return true;
}
/************************************************************************/
/*
打印堆
*/
/************************************************************************/
void MinHeap::printHeap()
{
for(int i=0;i<currentSize;i++)
{
cout<<heap[i]<<endl;
}
}
/************************************************************************/
/*
为堆进行排序,将堆顶数据和末尾数据进行条换,然后current--
对堆从顶端进行调整
重复以上动作,直到排序完成
*/
/************************************************************************/
void MinHeap::SortHeap()
{
if(IsEmpty())
{
return;
}
for(int i=1;i<currentSize;i++)
{
int temp=heap[0];
heap[0]=heap[currentSize-i];
heap[currentSize-i]=temp;
SiftDown(0,currentSize-i-1);
}
}
虽然是使用数组,但同样运用到树的概念。
heap[0] 就好比是一颗树的根节点,它的左右孩子分别为heap[1],heap[2]
对于任意一个位置i,它的左孩子是i*2+1,右孩子是i*2+2
插入一个数据后,从这个数据向上进行调整
删除堆顶后,将末尾数据放入堆顶,然后从堆顶向下调整