之前学习过了最大堆排序,但是后来每次温习重写的时候就又整不清楚了,想了一下,归根结底还是自己没把原理吃透,每次都是靠翻看以前的代码写出来的,写代码要建立的理解其原理的情况下,才能以不变应万变,所以今天再次仔仔细细的把最大堆的几个重要函数重新梳理一次,一定要吃透排序的原理,这里将几个函数写出来与大家一起分享
1.最大堆的构建思路
找到最后一个有子节点的节点,将此节点的数据保存到临时变量中,再在子节点中找出最大的与之比较,如果子节点比父节点大则将子节点的值赋给父节点,然后以此子节点为父节点继续向下比较,最后再将临时变量里保存的值赋给相应的位置
void Initialize(int *pData,int len)//这里用一个int 数组做示例
{
int currentSize=len-1;//len是树的长度,currentSize是最后一个数据的下标
//遍历每个父节点
for(int i=currentSize/2;i>=1;--i)
{
int temp=pData[i];//存放当前父节点的数据
int ci=i*2;//当前父节点的左节点
//以下循环是要找出存放此父节点值得位置满足最大堆的条件,子节点小于父节点
while(ci<=currentSize)
{
if(ci<currentSize&&pData[ci]<pData[ci+1])//寻找子节点中最大的节点
++ci;
if(pData[ci]<temp)//如果子节点的值小于temp的值,则退出
break;
else
{
pData[ci/2]=pData[ci];//将子节点的值赋给父节点
ci*=2;//向下移一层
}
}
pData[ci/2]=temp;
}
}
2.插入数据
将数据添加在最后一个节点,然后在依次向上寻找存放此数据的位置
void Insert(int data,int *pData,int len)
{
if(len==1)//等于1是没有数据的情况,默认第一个位置不存放数据
{
pData[len++]=data;
return;
}
int i=len++;//记录添加数据后的下标长度,即最后一个元素的位置,然后向上比较
while(i>1&&data>pData[i/2])//如果添加的数据比其父节点值大
{
pData[i]=pData[i/2];//将其父节点向下移
i/=2;//移向父节点
}
pData[i]=data;
}
3.删除数据
删除根节点数据,将最后一个数据放到根节点,再依次向下寻找存放此数据的位置,让其满足最大堆规则
void Delete(int *pData,int len)
{
if(len==1)
return;
int currentSize=len-1;
int temp=pData[currentSize--];//存放最后一个节点数据
//从第一个数据开始
int i=1;
int ci=i*2;
while(ci<=currentSize)
{
if(ci<currentSize&&pData[ci]<pData[ci+1])
++ci;
if(pData[ci]<temp)
break;
else
{
pData[ci/2]=pData[ci];
i=ci;
ci*=2;
}
}
pData[i]=temp;
}