最大堆排序

来源:互联网 发布:硬笔书法字帖推荐 知乎 编辑:程序博客网 时间:2024/06/08 17:24

之前学习过了最大堆排序,但是后来每次温习重写的时候就又整不清楚了,想了一下,归根结底还是自己没把原理吃透,每次都是靠翻看以前的代码写出来的,写代码要建立的理解其原理的情况下,才能以不变应万变,所以今天再次仔仔细细的把最大堆的几个重要函数重新梳理一次,一定要吃透排序的原理,这里将几个函数写出来与大家一起分享
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;}
原创粉丝点击