堆排序算法
记录一下今天学堆排序的心得。
首先,堆可以视为一棵完全二叉树。而完全二叉树具有以下的性质:
(不考虑边界情况,且根节点的序列下标为0)假设某节点的序列下标为i,那么它的父节点的序列下标为 (i-1)/2 ,它的左子节点为 2*i+1 ,右子节点为 2*i+2 。
根据以上这些信息,我们就可以构造一个最大/最小 堆了。
步骤如下(以最大堆为例):
- 将数组构造成为一个初始堆(自下而上)
- 堆排序处理
- 将堆顶元素移到最后的位置,调整[0,n-i]位置的堆(i=1,2,…n)
- 重复步骤3直到 i=n
先简单贴一下代码,有时间再补充…
// 主函数
public static void main(String []args)
{
int[] arr = {1,5,6,8,7,2,3,4,9};
HeapSort(arr);
for(int i=0;i<arr.length;i++)
{
System.out.println(arr[i]+" ");
}
}
// 构造大顶堆
public static void HeapSort(int []arr)
{
int n=arr.length-1;
for(int i=(n-1)/2;i>=0;i--)
{
HeapAdjust(arr,i,n);//数组 第一个开始的下标 总的长度
}//构造完初始大顶堆
for(int i=n;i>0;i--)//将堆顶的元素放到数组的末尾,重新调整前i-1个元素的堆
{
int temp=arr[i];
arr[i]=arr[0];
arr[0]=temp;
HeapAdjust(arr,0,i-1);
}
}
//调整堆内位置
public static void HeapAdjust(int []arr,int parent,int n)
{
int temp=arr[parent];//防止被覆盖
for(int i=parent*2+1;i<=n;i=i*2+1)
{
if(i<n&&arr[i]<arr[i+1])//子节点中选出较大值
{
i=i+1;
}
if(temp>=arr[i])
{
break;
}
arr[parent]=arr[i];
parent=i;
}
arr[parent]=temp;
}