一、综述
堆排序是选择排序中的一种,算法复杂度是O(nlogn),最坏最好都是这个。下面用Java实现一个堆排序,并用注释的方式解释了堆排序的思想和原理。
二、Java实现堆排序
import java.util.*;
public class Solution {
public int[] MySort (int[] arr) {
// 1. 根据adjustHeap的定义,先建立堆,需要从底层往上构建
for(int i = arr.length/2 - 1; i >= 0; i--){
adjustHeap(arr, i, arr.length);
}
// 2. 开始排序,每次交互堆顶元素到最后去,再把剩余元素调整为堆
for(int j = arr.length - 1; j > 0; j--){
swap(arr, 0, j);
adjustHeap(arr, 0, j);
}
return arr;
}
/**
* 调整堆,建立在大頂堆已经构建的基础上,此时i指向的元素不是最大的
* 需要逐层往下移动它,比较它的左右孩子,找到最大的节点和父节点替换
* 替换过后,子堆有可能不满足条件,需要递归调整
*/
public void adjustHeap(int[] arr, int i, int length){
if(arr == null || arr.length == 0) return;
int parent = arr[i];
Integer left = 2 * i + 1 >= length ? null : arr[2 * i + 1];
Integer right = 2 * i + 2 >= length ? null : arr[2 * i + 2];
if(null == left && null == right) return;
int curMaxIndex = i;
if(right == null){
if(left != null && left > parent){
curMaxIndex = 2 * i + 1;
}
}
//注意有右孩子,必然有左孩子,因为堆是完全二叉树
if(right != null){
if(left >= right && left > parent){
curMaxIndex = 2 * i + 1;
}else if(right >= left && right > parent){
curMaxIndex = 2 * i + 2;
}
}
if(curMaxIndex != i){
swap(arr, i, curMaxIndex);
//交换过后,递归调整子堆
adjustHeap(arr, curMaxIndex, length);
}
}
private void swap(int[] a, int i,int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
三、结果检验
public class maintest {
public static void main(String[] args) {
int[] a = { 45, 6, 43, 78, 12, 90, 23, 21, 41, 64, 31, 91, 81, 6 };
AHeapSort.HeapSort(a, a.length);
for (int e : a) {
System.out.print(e + " ");
}
}
}
//调用输出结果为:6 6 12 21 23 31 41 43 45 64 78 81 90 91