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

数据结构之堆排序

2013-11-01 08:14 190 查看
#include <iostream>
using namespacestd;
/*
将根节点root筛选成最大结点,注意root的【左右孩子】(root不用满足,不然就不用sift了)必须满足堆的性质了(即父节点必须大于左右孩子),最初拿到数据时,我们  是从倒数第一个有孩子的结点(n/2)开始的,而他的孩子是叶子,叶子满足堆的性质。

*/
void sift(int src[],introot,intn)
{
// 父结点,左右孩子的索引
int parent =root;
int lchild =parent*2;
int rchild =parent*2+1;

// 保存最大孩子的数据
int max_child;

// 保存最大孩子的索引,每次父节点跟左右孩子交换的时候,有可能会破坏子树的堆性质
// 当然只破坏左右子树中和父结点交换的那一棵而已
int max_child_index;

// 保存根结点的数据,每次父结点小于孩子结点的时候不需要跟孩子交换数据
// 只需要将孩子的数据复制到父结点就行了
int root_data =src[root];

// 如果存在左孩子
while(lchild <=n)
{
// 存在有孩子
if(rchild <=n)
{
//左孩子大于右孩子
if(src[lchild]>src[rchild])
{
max_child = src[lchild];
max_child_index =lchild;
}
//右孩子大于左孩子
else
{
max_child = src[rchild];
max_child_index =rchild;
}
//左右孩子中最大的孩子大于父节点
if(max_child >root_data)
{
src[parent] =max_child;
parent = max_child_index;
}
else
{
break;
}
}
else
{
if(src[lchild]>root_data)
{
src[parent] =lchild;
parent = lchild;
}
else
{
break;
}
}
lchild= parent*2;
rchild= parent*2+1;
}
src[parent] =root_data;
}

void build(int src[],intn)
{
// 一棵有n个结点的树,n/2之后的所有都是叶结点
for(introot =n/2;root >=0; --root)
{
sift(src,root,n);
}
}

void heapSort(int src[],intn)
{
// 将树初始化为堆
build(src,n);
for(inti =n;i >= 0;--i)
{
// 输出根结点
cout<<src[0]<<"";
// 将最后一个放到根结点,顺便把树的结点数目减一
src[0]= src[n--];
// 再将根结点的堆性质被破坏的数重新筛选成堆
sift(src, 0,n);
}
cout<<endl;
}

int main()
{
int src[10] = {4,5,6,7,8,9,1,2,3,0};
int n = 9;
//int src[6] = {2,5,4,3,1,6};
//int n= 5;
heapSort(src,n);
return0;
}


 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  堆排序