private void buildHeap(int[] h) { int l = h.length; //这里需要从下向上调整,因为从上向下调整只能让最小值下到底端,只有从下向上调整可以让最大值上到顶端 //shiftDown需要递归,如果不递归,这里只能保证最大的元素在堆顶,但是不能保证子分支都是最大堆
//这里下标 l/2 -1 是倒数第二层中从左到右最后一个非叶子节点(倒数第二层中最后一个含有子节点的节点)的数组下标 for (int i = (l / 2 - 1) ; i >= 0; i--) { shiftDown(h, i); } } private void shiftDown(int[] h, int i) { int l = h.length;
//右子节点的数组下标大于 数组最后一个元素下标,没有右子节点 if (2 * i + 2 > l - 1) {
//左子节点的数组下标大于数组最后一个元素的下标 if (2 * i + 1 > l - 1) { //没有左节点,不需要交换 return; } else { if (h[i] < h[2 * i + 1]) { //交换根和左子节点 swap(h, i, 2 * i + 1); shiftDown(h, 2 * i + 1); } else { //如果不需要交换,下面递归也不需要,因为调整是从下向上,如果这里没有交换,那么下面的子分支没有受到影响也不需要调整 return; } } } else { if (h[2 * i + 1] > h[2 * i + 2]) { //左节点大与右子节点 if (h[i] < h[2 * i + 1]) { //左子节点大于根节点 swap(h, i, 2 * i + 1); shiftDown(h, 2 * i + 1); } else { return; } } else { //右节点大 if (h[i] < h[2 * i + 2]) { swap(h, i, 2 * i + 2); shiftDown(h, 2 * i + 2); } else { return; } } } } private void swap(int[] h, int i, int j) { int temp = h[i]; h[i] = h[j]; h[j] = temp; }
标签:sort,下标,int,shiftDown,else,heap,return,节点 From: https://www.cnblogs.com/yanher/p/16875708.html