import java.util.ArrayList; public class HeapSorted { public static void main(String[] rags) { HeapSorted testSorted = new HeapSorted(); int[] input = {2,2,7,4,8,2,9,3,6,5}; int k = 4; System.out.println(testSorted.GetLeastNumbers_Solution(input, k)); } public ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) { ArrayList<Integer> res = new ArrayList<Integer>(); if (input == null || input.length == 0 || input.length < k) { return res; } if (k == 0) return res; int[] maxHeap = new int[k]; //初始化堆 for (int i = 0; i < maxHeap.length; i++) { maxHeap[i] = input[i]; } //将初始化的堆调整为最大堆。最大堆:根节点的值总是大于子树中任意节点的值 // 注意是--i,从下往上 for (int i = (maxHeap.length - 1) / 2; i >= 0; i--) { adjustHeap(maxHeap, i); } //遍历初始数组不断调整最大堆 for (int i = k; i < input.length; i++) { if (maxHeap[0] > input[i]) { maxHeap[0] = input[i]; adjustHeap(maxHeap, 0); // 是0位置,即根节点的值为最大值 } } for (int i = 0; i < maxHeap.length; i++) { res.add(maxHeap[i]); } return res; } static void adjustHeap(int maxHeap[], int i) { int index = i; int lchild = 2 * i + 1; //i的左孩子节点序号 int rchild = 2 * i + 2; //i的右孩子节点序号 if (index <= (maxHeap.length - 1) / 2) { //寻找子节点中最大的节点 if (lchild < maxHeap.length && maxHeap[index] < maxHeap[lchild]) { //左孩子大于index index = lchild; } if (rchild < maxHeap.length && maxHeap[index] < maxHeap[rchild]) { //右孩子大于index index = rchild; //此时index为左右孩子中较大的那个 } if (i != index) { //将节点与最大的子节点交换 int tmp = maxHeap[index]; maxHeap[index] = maxHeap[i]; maxHeap[i] = tmp; //交换后,子树可能不满足最大推,递归调整。 adjustHeap(maxHeap, index); //因为交换下来一个小的数字,要调整的是被交换的子树 } } } }
求N个数中最小的K的数 O(NlogK)
最新推荐文章于 2022-04-05 00:05:17 发布