堆排序(Heap Sort)
原理:将数组构造成一个大顶锥,此时根节点就是最大值,然后将根节点值与末尾值交换,然后将剩余的n-1个元素重新构造成大顶锥,得到次最大值,如此反复执行即可
大顶锥:完全二叉树,节点值大于等于左右孩子,所以根节点是最大值。当前节点下标i,那么做孩子为2i,右孩子为2i+1。
堆调整函数思想:当前节点与左右孩子比较,取较大值进行交换。。然后向下比较子树。。最后使得当前节点的值为其子树中的最大值
构建完整大顶锥思想:找到序列的所有节点(有孩子),然后按照从下往上,从右往左的顺序(也就是树的层序遍历反过来)对所有节点进行堆调整,这样得到一个完整的大顶锥
时间复杂度:
O
(
n
log
n
)
O(n\log n)
O(nlogn)
import java.util.Arrays;
public class test {
public static void HeapSort(int[] nums) {
int i;
for (i = nums.length/2 - 1; i >= 0; i--) {
HeapAdjust(nums, i, nums.length - 1);
}
for (i = nums.length - 1; i > 0; i--) {
swap(nums, 0, i);
HeapAdjust(nums, 0, i-1);
}
}
public static void HeapAdjust(int [] nums, int s, int m) {
int temp, j;
temp = nums[s];
for(j = 2*s; j <= m; j*=2) {
if(j < m && nums[j] < nums[j+1]) j++;
if (temp >= nums[j]) break;
nums[s] = nums[j];
s = j;
}
nums[s] = temp;
}
public static void swap(int [] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void main(String[] args) {
int [] nums = {9, 1, 5, 8, 3, 7, 4, 6, 2};
HeapSort(nums);
System.out.println(Arrays.toString(nums));
}
}