堆排序
建堆,移动最值,维护堆
时间复杂度 初始化建堆O(n),排序重建堆O(nlog(n)) 总时间复杂度 O(nlog(n)); 不稳定
代码实现:最大堆最小堆的区别只是在节点和子节点比较
package leet;
import org.junit.Test;
import java.util.Arrays;
/**
* @ClassName:Heap
* @Description:TODO
* @author:zgw
* @date:2022/9/27 21:39
*/
public class Heap {
@Test
public void test() {
int[] nums = new int[]{3, 3, 2, 1, 0};
System.out.println(Arrays.toString(nums));
Heap heap = new Heap();
heap.heapSort(nums);
}
private void heapSort(int[] nums) {
int n = nums.length;
// 0-n的下标堆 第一个不为叶子节点的下标 n/2 -1,可验证
for (int i = n / 2 - 1; i >= 0; i--) {
adjustHeap(nums, i, n);
}
// 建堆完成后,index0是最大值,交换到最末尾,然后对index0继续维护
for (int i = n - 1; i > 0; i--) {
int t = nums[0];
nums[0] = nums[i];
nums[i] = t;
adjustHeap(nums, 0, i);
}
System.out.println(Arrays.toString(nums));
}
private void adjustHeap(int[] nums, int index, int end) {
// 下面的循环一直移动t值,直到t比左右子节点大
int t = nums[index];
for (int i = 2 * index + 1; i < end; i = i * 2 + 1) {
// i=2*index+1为左子节点,i+1为右子节点 将i移动到左右子树中较大的一个
if (i + 1 < end && nums[i + 1] > nums[i]) {
i++;
}
if (nums[i] > t) {
// 较大子节点比t大则交换,并把index指向原来子树的位置,继续循环
nums[index] = nums[i];
nums[i] = t;
index = i;
} else {
break;
}
}
}
}
标签:index,堆排,nums,int,Heap,adjustHeap,节点
From: https://www.cnblogs.com/beichuang/p/16736186.html