作者:理想压力正比_635 | 来源:互联网 | 2023-09-08 09:19
在了解堆排序之前,基本的二叉树的概念是需要知道的
完全二叉树:叶子节点在最后一层或者次一层,且节点从左往右连续
大根堆:任何根节点都比他的左右子节点都要大
i为节点在数组中的索引,求节点的父节点:(i - 1) / 2, 求节点的左节点 i * 2 + 1,求节点的右节点 i * 2 + 2
在构建一个堆之前,我们需要先把他们的左右节点构建成堆,所以我们从下往上依次构建堆,由于叶子节点是没有子节点的,所以从最后一个节点的父节点开始构建,想画个个图,可是实力实在不允许那就都放在代码中吧,老铁干了这段代码,先写递归的吧,递归毕竟理解起来简单。
&#64;Testpublic void test() {int size &#61; 50;int[] array &#61; new int[size];for (int i &#61; 0; i < size; i&#43;&#43;) {array[i] &#61; (int) (Math.random() * 100);}heapify2(array);System.out.println(Arrays.toString(array));}public void heapify2(int[] array) {if (array &#61;&#61; null || array.length < 2) {return;}int parentNode &#61; (array.length - 2) / 2;for (int i &#61; parentNode; i >&#61; 0; i--) {sift2(array, i, array.length - 1);}for (int i &#61; array.length - 1; i > 0 ; i--) {swap(array, 0, i);sift2(array, 0, i - 1);}}public void sift2(int[] array, int currentNode, int length) {int left &#61; currentNode * 2 &#43; 1;int right &#61; currentNode * 2 &#43; 2;int max &#61; currentNode;if (left <&#61; length && array[left] > array[max]) {max &#61; left;}if (right <&#61; length && array[right] > array[max]) {max &#61; right;}if (max !&#61; currentNode) {swap(array, max, currentNode);sift2(array, max, length);}}
最主要的就是这个sift,通过不断交换&#xff0c;来达到大根堆的效果&#xff0c;接着就是非递归的写法&#xff0c;其实和递归的思想一样&#xff0c;我们交换后就以交换的节点来进行堆排
public void sift1(int[] array, int currentNode, int length) {int tmp &#61; currentNode;int j &#61; currentNode * 2 &#43; 1;while (j <&#61; length) {if (j &#43; 1 <&#61; length && array[j &#43; 1] > array[j]) {j &#61; j &#43; 1;}if (array[tmp] < array[j]) {swap(array, tmp, j);tmp &#61; j;j &#61; tmp * 2 &#43; 1;} else {break;}}}