您的位置:首页 > 其它

堆排序

2013-11-07 22:22 183 查看

代码一:对数组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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: