前言
给定一个数组:
String[] arr = {"S","O","H","G","B","C","E","F","M","L","A","D","L"}
请对数组进行排序
实现思路
1、构造堆
2、得到堆顶元素,这个值就是最大值
3、交换堆顶元素和数组中最后一个元素,此时所有元素中的最大元素已经放到合适的位置
4、对堆进行调整,重新让出了最后一个元素的剩余元素中的最大值放到堆顶。
5、重复2-4步骤,直到剩下一个元素为止。
代码实现
public class HeapSort {
//对source数组中的数据从小到大排序
public static void sort(Comparable[] source){
Comparable[] heap = new Comparable[source.length+1];
createHeap(source,heap);
//排序
int n = heap.length-1;
while (n>0){
//交换堆顶与n处元素
exch(heap,1,n);
n--;
//堆顶元素下沉
sink(heap,1,n);
}
//复制heap数组到source中
System.arraycopy(heap,1,source,0,source.length);
}
//根据原始数组,构造出堆
private static void createHeap(Comparable[] source,Comparable[] heap) {
//先复制原始数组到堆数组中
System.arraycopy(source,0,heap,1,source.length);
//从堆树中长度的一半开始左下沉算法
for (int i=(heap.length/2);i>0;i--){
sink(heap,i,heap.length-1);
}
/* int mid = heap.length / 2;
int range = heap.length-1;
while (mid > 0) {
sink(heap, mid, range);
mid--;
}*/
}
//在heap堆中,对target处的元素做下沉,范围是0-range
private static void sink(Comparable[] heap,int target,int range){
while (target*2<=range){
int max;
if (2*target+1>range){
max=target*2;
}else {
max = less(heap,2*target,2*target+1)?(2*target+1):(2*target);
}
if (!less(heap,target,max)){
break;
}
exch(heap,target,max);
target = max;
}
}
//判断heap堆中索引i元素是否小于索引j的元素
private static boolean less(Comparable[] heap,int i,int j){
return heap[i].compareTo(heap[j])<0;
}
//交换堆中i和j索引处的值
private static void exch(Comparable[] heap,int i,int j){
Comparable temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
}
测试:
public static void main(String[] args) {
Integer[] arr = {12,4,65,33,22,17,45,26,28};
HeapSort.sort(arr);
System.out.println(Arrays.toString(arr));
}