您的位置:首页 > 理论基础 > 数据结构算法

数据结构(五)堆排序

2018-01-28 11:17 134 查看
1、算法流程

(1)对原始数据构建大根堆:
A、从下至上,遍历每个非叶子父节点,保证每个非叶子父节点都比它的左右子节点来的大,非叶子父节点的对应索引范围为[0,n/2-1];
B、在遍历每个非叶子父节点的时候,如果发生该节点交换(下沉),那么要递归下去
(2)交换大根堆构建后的数组的首个元素与末尾元素,这时候数组的末尾数值最大,排除该元素排序。
(3)接着因为这个堆,就相当于堆顶元素被替换成了新的元素,其他元素都是不变的,因此接着只需要从堆顶开始做下沉操作,从新构架最大堆(不需要遍历调整所有的非叶子节点)。
2、代码实现
//堆排序,对于每个非叶子节点,如果比叶子节点小,那么就要下沉递归该数值
void min_sink(int*data,int node,int length)
{
if (node>=(length/2))
return;
int sink_flag= false;
int min_index=node;
int min_data=data[node];
for(int i=1;i<=2;i++)
{

if (min_data<data[node*2+i]&&(node*2+i)<length)
{
min_data=data[node*2+i];
min_index=node*2+i;
sink_flag=true;
}
}
if (sink_flag)//如果发生非叶子节点数值下沉,那么就要递归子下沉非叶子节点
{
swap(data[node],data[min_index]);
min_sink(data,min_index,length);
}

}

void heap_sort(int *data,int length)
{
for(int i=length/2-1;i>=0;i--)//遍历每个非叶子节点,构建大根堆
min_sink(data,i,length);
for(int count=1;count<length;count++)//从第二次开始遍历的时候,只需要调整堆顶,其他的非叶子节点不用遍历
{
swap(data[0],data[length-count]);
min_sink(data,0,length-count);

}

}

int test_sort() {

int data[10]={5,1,6,7,8,4,2,2,10,13};

heap_sort(data,10);
for(int i=0;i<10;i++)
{
std::cout<<data[i]<<std::endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: