码迷,mamicode.com
首页 > 编程语言 > 详细

堆排序

时间:2016-03-28 21:52:13      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:

一个数组可以看成是一棵树。(数组下标0 是根节点     2i+1是节点的左孩子  2i+2是右孩子 )

这棵树的父亲节点 大于 左右孩子节点 ,称之为大顶堆。

这棵树的父亲节点 小于 左右孩子节点 ,称之为小顶堆。

堆排序 (以大顶堆 为例) 主要分为两个 部分 

1>调整节点

void  Adjust(int arr[],int nLen,int Index)
{
    int MaxIndex;
    //判断要调整的节点 有几个孩子 
    if(2*Index+1<= nLen-1)
    {
        //这个 判断进来 证明至少有一个 孩子 记住孩子里面数最大的
        if(2*Index+2<= nLen-1)
        {
            //有左 右两个 孩子
            if( arr[2*Index+2] >arr[2*Index+1] )    
                MaxIndex=2*Index+2;
            else
                MaxIndex=2*Index+1;  
         }
        else
        {
            //只有一个左 孩子
            MaxIndex=2*Index+1;  
        }
    }
    else
    {
        //没有左孩子 不用调整了
        return ;
    }
    //将孩子里面最大的数和父亲节点的数进行比较
    if(arr[MaxIndex]> arr[Index])
    {
        //如果大于父亲节点 就进行交换 
        arr[MaxIndex]=arr[MaxIndex]^arr[Index];
        arr[Index]=arr[MaxIndex]^arr[Index];
        arr[MaxIndex]=arr[MaxIndex]^arr[Index];
        //交换完成 要 调整 交换过的节点
        Adjust(arr, nLen,MaxIndex );
     }

}                       

 

2>将无序的数组变成 大顶堆

void CreateHeap(int arr[],int nLen)
{
    //参数检查
    if(arr==NULL || nLen<=0) return ;
    //创建 大顶堆
    //从最后一个父亲节点开始创建
    for(int i=nLen/2-1;i>=0;i++)
    {
        Adjust(arr,nLen,Index);
    }
    //循环 将 大顶堆的 第一个元素和 最后一个元素进行交换
    for(int i=nLen-1;i>0;i--)
    {
          arr[0]=arr[0]^arr[i];
          arr[i]=arr[0]^arr[i];
          arr[0]=arr[0]^arr[i];
          //对改动的节点 重新调整 
          Adjust(arr,i,0);
    }
}    
            

要点:

1>每次调用 adjust 函数进行调整 如果调整成功 一定要将有改变过的 孩子节点 继续调用adjust 调整

2>adjust 函数里面要做好 对有无 孩子 有几个孩子的判断

 

后记:

堆排序是一种选择排序.

时间复杂度是O(nlog2n)


//1 从最后一个 根节点开始调用循环节点调整函数直到根节点 
//2 将这个堆的顶和最后一个元素 替换 
//3 因为改变了 头 所以把头得索引当参数 传进 循环节点 调整函数 数组长度--
//4 循环2,3步骤

 

重点在 节点调整函数 上面
这个函数 只处理三个节点的 关系
1>根节点
2>根的左孩子
3>根的右孩子
所以 一进到这个函数里 处理逻辑是
1>有左孩子么 没有 return;
2>有右孩子么
没有 让 左孩子成为最大索引
有 找左右孩子的最大值索引
3>用最大值 跟根比较
比根大 就交换
4>看发生过交换么
发生过交换 要将被 改变过的孩子索引当参数递归调用此函数

 

堆排序

标签:

原文地址:http://www.cnblogs.com/ming-rui/p/5330396.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!