import java.util.Arrays;
public class Heapsort2 {
/**
* 表示堆里的所有元素个数
*/
private int heapLength;
/**
* 表示堆里未排序的个数
*/
private int heapSize;
/**
* 堆所在的数组
*/
private int[] arr;
public Heapsort2(int[] arr){
this.arr = arr;
this.heapSize = arr.length;
this.heapLength = arr.length;
}
/**
* 获取下标为i的节点的父节点坐标
* @param i 下标为i的节点
* @return 下标为i的节点的父节点坐标
*/
private int parent(int i){
return (i+1) / 2 - 1;
}
/**
* 获取下标为i的节点的左孩子的节点的坐标
* @param i 下标为i的节点
* @return 下标为i的节点的左孩子的节点的坐标
*/
private int left(int i){
return 2*(i+1) - 1;
}
/**
* 获取下标为i的节点的右孩子的节点的坐标
* @param i 下标为i的节点
* @return 下标为i的节点的右孩子的节点的坐标
*/
private int right(int i){
return 2*(i+1);
}
/**
* 维护坐标为i的根节点的最小堆,即让坐标为i的节点的值小于其左右孩子节点的值。
* @param i 坐标为i的根节点
*/
private void minHeapify(int i) {
int l = this.left(i);
int r = this.right(i);
int least = i;
if(l < this.heapSize && this.arr[l] < this.arr[least])
least = l;
if(r < this.heapSize && this.arr[r] < this.arr[least])
least = r;
if(least != i){
swap(least, i);
this.minHeapify(least);
}
}
/**
* 根据数组构建最大堆
*/
private void buildMinHeap(){
for(int i = (this.heapLength / 2) - 1; i >= 0; i--)
this.minHeapify(i);
}
/**
* 对arr进行堆排序。
* @原理 假设数组有n个元素。首先把数组的所有元素堆排列成一个最小堆的形式。
* 此时,最小的元素为第一个元素。然后,把数组的第一个元素与最后一个
* 元素交换。以此类推。
*/
public void heapsort(){
this.buildMinHeap();
for(int i = this.arr.length - 1; i > 0; i--){
this.swap(0, i);
this.heapSize--;
this.minHeapify(0);
}
}
@Override
public String toString() {
return Arrays.toString(this.arr);
}
/**
* 交换数组两个元素的位置
* @param a
* @param b
*/
private void swap(int a, int b){
arr[b] = arr[a] ^ arr[b];
arr[a] = arr[b] ^ arr[a];
arr[b] = arr[b] ^ arr[a];
}
public static void main(String[] args) {
// 示例
int[] arr = {
1, 8, 7, 2, 9, 5, 12, 5, 9};
Heapsort2 heapsort = new Heapsort2(arr);
heapsort.heapsort();
System.out.println(heapsort);
}
}
结果: