堆排序


代码一:对数组a,使用堆进行排序,建立堆和排序输出都在数组a上,代码挺经典,不用递归

#include "stdafx.h" 
#include<iostream>
using namespace std;


void adjustHeap(int a[],int index,int length)//从把节点index和index*2与index*2+1调整为最大堆,并且把后面产生的影响消除。一句话就是把index放到合适的位置,前提是出了index和index*2,index*2+1不保证堆性质外,其他节点都有堆性质。适用于把一个堆的index位置元素输出后,用了新来的元素替代后重新调整堆的需要。
{
     int record = a[index];
     for(int j = 2*index;j<length;j*=2)//
     {
             if(a[j]<a[j+1])//找到较大的儿子
             {
                   j = j+1;
             }
             if(record>a[j])//如果record比a[j]大,那表示不需要再往下找合适的地点放置record了
             {
                   break;
             }
//如果record比当前的a[j]小,那么还需要继续往下层寻找record应该放置的地点
             a[index] = a[j];
             index = j;
     }
     a[index] = record;    
}


void add(int *a,int size,int val)//往堆里size位置插入一个元素到并且向上调整堆,使其仍然保持堆。
{


     //*(a+size) = 100;
     //display(a,size);
     int tmp = size;//tmp表示应该插入的位置
     int parent = tmp/2;
     while(parent>0)
     {
        if(*(a+parent) > val)//如果父节点比val大,那么表示val不可能再往上升了。
                       break;
        *(a+tmp) = *(a+parent);//如果父节点比val小,说明val还应该往上升,才能调整成为大根堆
        tmp = parent;
        parent = tmp/2;
     } 
     *(a+tmp) = val;
}


void display(int a[], int len)
{
     for(int i=1;i<len;i++)
             cout<<a[i]<<" ";
     cout<<endl;
}
int main()
{   int a[20] = {0,49,38,65,97,76,13,27,49}; 
    int len = 9;
    display(a,len);
    for(int i=len/2;i>0;i--)//从最后一个非叶子节点开始调整
    {
            adjustHeap(a,i,len);
    }
add(a,len,100);
len++;
    display(a,len);
    for(int i=0;i<len-1;i++)//把堆顶不断的交换到到最后一个节点,知道整个数组有序。交换树根和最后一个叶子节点,这样最大的数就到数组最后去了,然后在调整前面的未排序节点
    {
            int tmp = a[1];
            a[1] = a[len-1-i];
            a[len-1-i] = tmp;
            adjustHeap(a,1,len-2-i);
    }
    display(a,len);
    getchar();
    return 0;
}

代码二:调整堆时使用递归

/*****************************************************************************
 函 数 名  : heap_sort
 功能描述  : 堆排序 
 输入参数  : array  待调整的堆数组
             length 数组的长度
 输出参数  : 无
 返 回 值  : 无 
 修改历史      :
  1.日    期   : 
    作    者   : 
    修改内容   : 

*****************************************************************************/
void heap_sort(int *array, int length)
{
    int i = 0;
    
    if (NULL == array || 0 == length)
    {
        return;
    }
    
    //构造大顶堆 
    for (i = length / 2 - 1; i >= 0; i--)
    {
        heap_adjust(array, i, length);
    }
    
    //从最后一个元素开始对数组进行调整,不断缩小调整的范围直到第一个元素 
    for (i = length - 1; i > 0; i--)
    {
        //交换第一个元素和当前的最后一个元素,保证当前的最后一个元素在当前数组中是最大的 
        swap(array[0], array[i]);
        
        //调整完后的第一个元素是当前数组的最大元素 
        heap_adjust(array, 0, i);
    }
}

/*****************************************************************************
 函 数 名  : heap_adjust
 功能描述  : 根据数组构建大顶堆 
 输入参数  : array  待调整的堆数组
             index  待调整的数组元素的位置
             length 数组的长度
 输出参数  : 无
 返 回 值  : 无 
 修改历史      :
  1.日    期   : 
    作    者   : 
    修改内容   : 

*****************************************************************************/
void heap_adjust(int *array, int index, int length)
{
    int child;
    int temp = array[index];
    
    if (2 * index + 1 >= length)
    {
        return;
    }

    //子结点位置 = 2 * 父结点位置 + 1
    child = 2 * index + 1;
        
    //得到子结点中较大的结点 
    if (child < length - 1 && array[child + 1] > array[child])
    {
        ++child;
    }
            
    //如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点 
    if (temp < array[child])
    {
        array[index] = array[child];
    }
    else
    {
        return;
    }
        
    //最后把需要调整的元素值放到合适的位置 
    array[child] = temp;
    
    heap_adjust(array, child, length);
}

非递归版二
/*****************************************************************************
 函 数 名  : heap_adjust
 功能描述  : 根据数组构建大顶堆 
 输入参数  : array  待调整的堆数组
             index  待调整的数组元素的位置
             length 数组的长度
 输出参数  : 无
 返 回 值  : 无 
 修改历史      :
  1.日    期   : 2012/08/23
    作    者   : liguangting
    修改内容   : 

*****************************************************************************/
void heap_adjust(int *array, int index, int length)
{
    int child;
    int temp = array[index];
    
    for (; 2 * index + 1 < length; index = child)
    {
        //子结点位置 = 2 * 父结点位置 + 1
        child = 2 * index + 1;
        
        //得到子结点中较大的结点 
        if (child < length - 1 && array[child + 1] > array[child])
        {
            ++child;
        }
            
        //如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点 
        if (temp < array[child])
        {
            array[index] = array[child]; index=child;
        }
        else
        {
            break;
        }
        
 
    }       //最后把需要调整的元素值放到合适的位置 
        array[child] = temp;
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zlingh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值