堆排序

来源:互联网 发布:阿里云邮箱下载 编辑:程序博客网 时间:2024/06/05 14:13


代码一:对数组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;}

原创粉丝点击