1.用户输入依次输入想要放入的数据(顺序建立) 即:每一次来一个数据,每一次在堆的末尾添加数据,并通过heapInsert方法判断新添加的数据该存放在哪个位置(时间复杂度:O(N*LogN)) private static void heapInsert(int[] arr, int index) { while (arr[index] > arr[(index - 1) / 2]) { exchange(arr, index, (index - 1) / 2); index = (index - 1) / 2; } }
2.数组已经确定的情况下,逆向建立(时间复杂度:O(N))
实现思路:把数组想象成未排序的大根堆(小根堆),然后从最尾层开始heapIfy(),因为最尾层的每一个子节点都可以看成是一颗完全二叉树,最尾层完成heapIfy,然后是倒数第二层、倒数第三层……
对于任意一个节点(index处,即arr[index]),它的左子节点和右子节点的索引分别是left==2*index+1和right==2*index+2,取得二者较大的arr值和父节点比较,如果比父节点大则和父节点交换位置,此时不要忘记index的值要改变
private static void heapIfy(int[] arr, int index, int heaSize) { int left = 2 * index + 1;//左叶子节点的索引 while (left < heaSize) { //确定左右子叶子节点的较大节点的索引 int lagerIndex = (left + 1) < heaSize && arr[left + 1] < arr[left] ? left : left + 1; if (arr[lagerIndex] > arr[index]) { exchange(arr, lagerIndex, index); } //index = lagerIndex; left = 2 * lagerIndex + 1; } }