1.问题引入:
2.实现步骤:
3.构造堆的方法:
4.堆排序的过程:
5.源代码:
package heap;
import java.nio.channels.Pipe.SinkChannel;
import javax.swing.text.AbstractDocument.LeafElement;
public class heapSort {
//判断heap堆中索引i处的值是否比索引j处的值小
private static boolean less(Comparable[] heap,int i,int j){
return heap[i].compareTo(heap[j])<0;
}
//交换heap堆中索引i处和索引j处的值
private static void exch(Comparable[] heap,int i,int j){
Comparable temp=heap[i];
heap[i]=heap[j];
heap[j]=temp;
}
//根据元素组source构建出堆数组heap
private static void createHeap(Comparable[] source,Comparable[] heap){
//把source中的元素拷贝到heap中,heap中的元素就形成了一个无序的堆
System.arraycopy(source, 0, heap, 1, source.length);
//对堆中的元素做下沉调整,(从数组长度的一般开始,往索引1处开始扫描,(从右往左),因为根据堆的特性,数组后一半元素都是叶子节点,无需下沉处理
for(int i=heap.length/2;i>0;i--){
sink(heap, i, heap.length-1);
}
}
//对source数组中的数据按从小到大的顺序进行排序
public static void sort(Comparable[] source){
//构建堆
Comparable[] heap =new Comparable[source.length+1];
createHeap(source, heap);
//定义一个变量,记录未排序元素中的最大索引值
int N=heap.length-1;
//通过循环,交换1索引处和排序元素中最大索引处的值
while(N!=1){
exch(heap, 1, N);
//排序交换后最大元素所在的索引,让它不要参与堆的下沉调整
N--;
//需要对索引1处的元素进行下沉调整
sink(heap, 1, N);
}
//把heap中的数据复制到原数组中即可
System.arraycopy(heap, 1,source,0,source. length);
}
//在heap堆中,对target处的元素做下沉,范围是0~range
private static void sink(Comparable[] heap,int target,int range){
//同堆中sink如出一辙
while(2*target<=range){
int max;
//找出当前节点的较大子节点
if(2*target+1<=range){
if(less(heap,2*target,2*target+1)){
max=2*target+1;
}else{
max=2*target;
}
}else{
max=2*target;
}
//比较当前节点的值和较大子节点的值
//如果当前节点的值大于其最大子节点的值那就不需要交换
if(!less(heap, target,max)){
break;
}
exch(heap,target,max);
//变换target的值
target=max;
}
}
}
6.测试类:
package heap;
import java.util.Arrays;
public class heapSortTest {
public static void main(String[] args) {
//创建待排序数组
String[] source ={"G","A","C","F","D","E","B"};
//通过heapSort的sort方法进行排序
heapSort.sort(source);
//打印输出排序后的数组
System.out.println(Arrays.toString(source));
}
}
7.测试结果: