堆排序 ——大顶堆
大顶堆和小顶堆的差别在与大顶堆的根节点比它的子节点和叶子节点都要大,大顶堆输出的时候是正序的而小顶堆是逆序的
同样的也是有两步
1,堆化
2,下调
public class _03_堆排序大顶堆 {
public static void main(String[] args) {
int A[] = {1,2,9,7,6,3,4,2};
sort(A);
for (int i = 0; i < A.length; i++) {
System.out.print(A[i]+" ");
}
}
//进行堆化
public static void MaxHeap(int[] A) {
int n=A.length;
for (int i =n/2-1; i>=0; i--) {
MaxHeapFixDown(A,i,n);
}
}
private static void MaxHeapFixDown(int[] A, int i, int n) {
//找到i的左右孩子
int left = 2*i+1;
int right= 2*i+2;
//如果它的左孩子已经越界,那么i就是叶子节点
if(left>=n)return;
int Max=left;
if(right<n) {
if(A[right]>A[left]) {
Max=right;
}
}
//如果比它两个孩子大就不用调整
if(A[i]>=A[Max])return;
int temp=A[i];
A[i]=A[Max];
A[Max]=temp;
//大孩子那个位置的值发生变化,i变更大孩子的那个位置,进行递归调整
MaxHeapFixDown(A, Max, n);
}
public static void sort(int[] A) {
//先对A进行堆化
MaxHeap(A);
for (int x =A.length-1;x>=0 ; x--) {
int temp=A[0];
A[0]=A[x];
A[x]=temp;
//缩小堆的范围,对堆顶进行向下调整
MaxHeapFixDown(A,0,x);
}
}
}