由下至上的堆有序化
如果堆的有序状态因为某个节点的插入而失衡,这时我们就需要通过交换它和它的父节点来进行调节.这个过程很简单,swim()方法中的循环可以保证只有位置k上的节点大于它的父节点时堆的有序状态才会被打破,因此只要该节点不再大于它的父节点,堆的有序状态就恢复了,至于方法名,取swim().
private void swim(int k){ while(k>1&&A[k/2]<A[k]){ exch(A,k,k/2); k/=2; } }
由上至下的堆有序化
如果堆的有序状态因为某个节点变得比它的两个子节点或者其中之一更小了而被打破了,那么我们可以通过将它和它的两个子节点中的较大者交换来恢复堆.交换可能会在子节点处继续打破堆有序的状态,因此我们需要不断地用相同的方式来恢复堆,当一个节点太小时,需要将它下沉到堆的更底层.代码方法名为sink()
private void sink(int k){ while(2*k<=N){ int j=2*k; if(j<N&&A[j]<A[j+1])j+=1; if(A[j]>A[k])break; exch(A,k,j); k=j; } }
堆排序
public class MaxPQ {
public static void main(String[] args) {
int A[] = {2, 4, 1, 4, 4, 5, 56, 3, 21, 25, 34, 51, 45, 2, 4, 2, 423, 2};
sort(A);
show(A);
}
public static void show(int[] A) {
for (int i = 0; i < A.length; i++) {
System.out.print(A[i] + " ");
}
}
public static void sort(int[] A) {
int N = A.length-1;
for (int i = N / 2; i >= 1; i--) {
sink(A, i, N);
}
while (N > 1) {
exch(A, 1, N--);
sink(A, 1, N);
}
}
public static void sink(int[] A, int k, int N) {
while (2 * k <= N) {
int j = 2 * k;
if (j < N && A[j] <= A[j + 1])
j++;
if (A[k] > A[j])
break;
exch(A, k, j);
k = j;
}
}
public static void exch(int[] A, int k, int j) {
int temp = A[k];
A[k] = A[j];
A[j] = temp;
}
}
需要仔细琢磨.