堆排序算法首先将所有元素(从未排序的数组)插入堆中,然后从堆的根节点依次删除,直到堆空为止。本文主要利用现有数组进行就地排序,具体做法是,当删除一个元素时,只是将数组中的第一个元素与最后一个元素交换位置而不是移除,同时减小堆的大小,即数组大小,然后再对第一个元素进行堆化。持续这个过程直到剩余元素为1.
在数组中直接进行堆排序,需要知道几个参数,即最后一个元素的位置是i=count-1,count为数组大小,则最后一个元素的双亲位置为(count-1)/2。任意一个节点j的左子节点位置l=2*j+1,右子节点位置r=2*j+2.
代码:
-
public class HeapSort { -
public static void swap(int[] data,int i,int j) -
{ -
if(i==j) -
return; -
data[i]=data[i]+data[j]; -
data[j]=data[i]-data[j]; -
data[i]=data[i]-data[j]; -
} -
public static int[] heapSort(int[] data) -
{ -
for(int i=0;i<data.length;i++)//控制堆大小。 -
{ -
//每次遍历创建最大堆,并且将堆顶元素放至最后一个,并将遍历的最后一位位置逐个左移。 -
createMaxHeap(data,data.length-1-i);//堆化 -
swap(data,0,data.length-1-i);//交换第一个元素与最后一个元素,即获取当前最大值 -
print(data); -
} -
return data; -
} -
public static void createMaxHeap(int[] data,int lastIndex) -
{ -
for(int i=(lastIndex-1)/2;i>=0;i--) -
{ -
//保存当前正在判断的节点 -
int k=i; -
//若当前节点存在 -
while(2*k+1<=lastIndex) -
{ -
//biggerIndex总是记录较大节点的值,先赋值为当前判断节点的左子节点 -
int biggerIndex=2*k+1; -
if(biggerIndex<lastIndex) -
{ -
//若右子节点存在,否则此时biggerIndex应该等于lastIndex -
if(data[biggerIndex]<data[biggerIndex+1]) -
{ -
//若右子节点值比左子节点值大,则biggerIndex记录的是右子节点的值 -
biggerIndex++; -
} -
} -
if(data[k]<data[biggerIndex]) -
{ -
//若当前节点值比子节点最大值小,则交换两者的值,交换后将biggerIndex值赋给k -
swap(data,k,biggerIndex); -
k=biggerIndex; -
} -
else -
break; -
} -
} -
} -
public static void print(int[] data) -
{ -
for(int i=0;i<data.length;i++) -
System.out.print(data[i]+" "); -
System.out.println(); -
} -
public static void main(String[] args) -
{ -
int[] data= {89, 66, 39, 78, 40, 56, 3, 13, 20, 95}; -
System.out.println("堆排序的序列变化:"); -
int[] ans=heapSort(data); -
System.out.println("堆排序后的序列:"); -
for(int i=0;i<data.length;i++) -
System.out.print(data[i]+" "); -
} -
}
测试结果:
-
堆排序的序列变化: -
40 89 56 78 66 39 3 13 20 95 -
20 78 56 40 66 39 3 13 89 95 -
13 66 56 40 20 39 3 78 89 95 -
3 40 56 13 20 39 66 78 89 95 -
3 40 39 13 20 56 66 78 89 95 -
3 20 39 13 40 56 66 78 89 95 -
13 20 3 39 40 56 66 78 89 95 -
3 13 20 39 40 56 66 78 89 95 -
3 13 20 39 40 56 66 78 89 95 -
3 13 20 39 40 56 66 78 89 95 -
堆排序后的序列: -
3 13 20 39 40 56 66 78 89 95
堆排序算法详解
本文详细介绍了一种高效的排序算法——堆排序。通过实例演示了如何利用最大堆实现就地排序,展示了具体的实现步骤与代码,包括创建最大堆、调整堆结构等关键环节。
510

被折叠的 条评论
为什么被折叠?



