import java.util.*;
public class HeapSort{
public static void main(String[] args){
int arr[] = {20,40,30,10,90,70}; // 原始数组
heapsort( arr , arr.length ); // 进行堆排序
System.out.println(Arrays.toString(arr)); //打印排序好后的数组
}
public static void heapsort(int heap[] , int n){
// n表示heap[]中有多个少元素
// 数组heap表示的是从索引0到lastIndex之间的堆
for ( int rootIndex = n/2-1; rootIndex >= 0; rootIndex-- ){ // 索引rootIndex处的节点是半堆的根
reheap(heap,rootIndex,n-1); //重建堆和排序
System.out.println(Arrays.toString(heap)+"for1"); // 跟踪数组变化
}
swap(heap,0,n-1); //将最大的元素放到最后面,这样下面继续排序,就可以忽视这个节点了
System.out.println(Arrays.toString(heap)+"swap");
//逐渐删除堆的规模
for (int lastIndex = n-2 ; lastIndex >=0 ; lastIndex--){ //
reheap(heap, 0 , lastIndex); //重建堆和排序
System.out.println(Arrays.toString(heap)+"for"); // 跟踪数组变化
swap(heap,0,lastIndex); // 交换
System.out.println(Arrays.toString(heap)+"swap2"); // 跟踪数组变化
}
}
private static void reheap(int heap[] , int BrootIndex , int BlastIndex){
// 索引BrootIndex处的节点是半堆的根
boolean done = false;
int tmp = heap[BrootIndex]; // 将半堆的根的值 保存到临时变量tmp中
int leftChildIndex = 2* BrootIndex+1; //半堆的根的左子节点
// int counter = 0 统计while执行的次数;
while (!done && (leftChildIndex <= BlastIndex)){ // 通过左子节点索引是否大于BlastIndex来判断g半堆的根节点是否有左子节点
int largerChildIndex = leftChildIndex; //
int rightChildIndex = leftChildIndex + 1 ; // 半堆的根的右子节点
// 判断半堆的根是否有右子节点
if ((rightChildIndex <= BlastIndex ) && (heap[rightChildIndex] > heap[largerChildIndex]) ){
largerChildIndex = rightChildIndex;
}
if (tmp < heap[largerChildIndex] ){ // 当半堆的根的值小于其子节点中的最大值,则将该子节点移动到半堆的根
// 将左子节点的值给 半堆根节点
heap[BrootIndex] = heap[largerChildIndex];
//除了上面要交换子左子节点与根节点的值之外,还要将他们的索引也互换
BrootIndex = largerChildIndex;
leftChildIndex = 2*BrootIndex+1;
// System.out.println("跟踪BrootIndex 在if的值:"+ BrootIndex); //
}
else
done = true; // 关键的地方:用done来判断是否已经将半堆转化为堆
// counter ++; 统计while执行的次数
}
// 将半堆的根的值 给 新的左子节点
heap[BrootIndex] = tmp ;
// System.out.println(Arrays.toString(heap)+"while"); // 跟踪数组变化
}
public static void swap( int heap[] , int a , int n){
int temp;
temp = heap[a];
heap[a] = heap[n];
heap[n] = temp;
}
}
|