您的位置:首页 > 其它

(排序详解之 堆排序)

2013-08-15 23:44 211 查看

堆排序

 

本文将介绍一下堆排序的过程。

 

要点:(最小堆为例)

1.      调整堆函数:传入节点索引,对比当前节点与父节点大小,如果小于则交换位置,以父节点位置递归执行。

2.      设index=Arr.Count/ 2 -1 ,取到index位置的子节点,将子节点和当前节点依次传入递归函数执行,i∈[0,index],i--循环执行

3.      每次移除根节点,执行1,2过程,直到数组中没有节点

 

详细过程:

 

还是以一个数组为开始:

5 , 1 ,9 ,3 ,7 ,4 ,8 ,6 ,2

 

我们开始建立堆(本文讨论二插堆),规则是这样的,从第一个元素开始,它的索引为I,那么2*i+1和2*i+2是它的后代

 

 

括号内为索引值:

 


 

 

堆建立好了,现在开始调整堆并排序。

第一步,从index= arr.Count/2 – 1 = 9/2-1 = 3开始,

 

 


 


 

 

                          

 

第二步,index = 2

 

 

 


 


 

 

 

 


 

 

 



 

 

 


第三步,index = 1

 

 

 


 

 

 


 

 

 

 


Index = 0
,发现不用调整,第一轮执行完毕,因此移除第一项,对接下来的数组做同样的操作,在此就不一一演示了。

 

参考代码:

public List<int>HeapSort(List<int> arr)
{

var ret = new List<int>();

while (arr.Count > 0)
{
for (int i = arr.Count / 2 - 1;i >= 0; i--)
{
if (i > 0)
HeapMerge(arr, i);

HeapMerge(arr, i * 2 + 1);

if (i * 2 + 2 <=arr.Count - 1)
HeapMerge(arr, i * 2 +2);

}

ret.Add(arr[0]);
arr.RemoveAt(0);
}

return ret;
}

//construct heap
private void HeapMerge(List<int>arr,int index)
{
if (index > 0 &&arr[index] < arr[(index-1)/2])
{
var tmp = arr[index];
arr[index] = arr[(index-1)/2];
arr[(index-1)/2] = tmp;
HeapMerge(arr,(index-1)/2);
}
}

 

希望现在您已经很清楚二插堆和堆排序了。

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