标签:heap index string 循环 integer floor 二叉树 最大 dex
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值总是小于(或者大于)它的父节点,前者称为大顶堆,后者成为小顶堆
大顶堆即父结点的值总是大于孩子结点
逻辑表示(二叉树)
物理表示(数组)
arr[i] | 11 | 7 | 5 | 3 | 2 | 4 |
---|---|---|---|---|---|---|
i(下标) | 0 | 1 | 2 | 3 | 4 | 5 |
不难发现一下几点
对一个结点进行下沉操作就是比较该结点是否比其左右孩子结点大,如果是就操作完成;如果否就将其和左右孩子结点中较大的一个进行交换,再对交换的孩子结点进行下沉操作
堆化就是将一个完全无序的数组使其满足堆的定义
做法是从倒数第一个非叶子结点开始到树根结点每个结点依次进行下沉操作,从而使其满足堆
当一个数组满足堆,其树根结点数字即为最大值,将其和未有序部分数组的末尾元素交换,将其固定到合适的位置.此时堆顶不满足父结点的值大于孩子结点的性质,需要对堆顶结点进行下沉操作
public class Heapsort {
private static void sink(Comparable[] arr,int currentIndex,int N){
int lChildIndex,rChildIndex;
while (true){
lChildIndex=2*currentIndex+1;
rChildIndex=2*currentIndex+2;
if(lChildIndex>=N){
//目标节点是叶子节点
break;
}else {
//目标节点有孩子
int largerIndex;//左右孩子中较大的一个
if(rChildIndex<N) {
//目标节点有左右孩子
largerIndex = (arr[lChildIndex].compareTo(arr[rChildIndex]) == 1) ? lChildIndex : rChildIndex;
}else {
//目标结点只有左孩子
largerIndex=lChildIndex;
}
if(arr[currentIndex].compareTo(arr[largerIndex])<0){
//目标节点小于子节点
swap(arr,currentIndex,largerIndex);
currentIndex=largerIndex;
}else {
break;
}
}
}
}
private static void swap(Comparable[] arr,int i,int j){
//交换两个下标位置的元素
Comparable temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public static void sort(Comparable[] arr){
int length=arr.length;
for(int i=(length-1)/2;i>=0;i--){//堆化
sink(arr,i,length);
}
for(int i=length;i>0;i--){
swap(arr,0,i-1);//固定最大值
sink(arr,0,i-1);//对堆顶进行下沉操作
}
}
public static void main(String[] args) {
Integer[] arr={20,30,20,20,90,40,70,110,60,10,100,50,80};
sort(arr);
for(int i:arr){
System.out.print(i+",");
}
}
}
标签:heap index string 循环 integer floor 二叉树 最大 dex
原文地址:https://www.cnblogs.com/redo19990701/p/12541997.html