package cn.com.dom4j.sort; import java.util.Arrays; public class Test2 { /** * 堆排序 */ public static <AnyType extends Comparable<? super AnyType>> void heapSort(AnyType[] a) { // buildHeap for (int i = a.length / 2; i >= 0; i--) { // 将数组值按初始顺序放入堆中, 从根节点执行下滤操作将构建一个堆 percolateDown(a, i, a.length); } // deleteMax for (int i = a.length - 1; i > 0; i--) { // 在构建了一个 max堆后, 将根节点与最后一个元素互换, 同时将堆的大小 -1, 调整位置, 再次实现堆序 // 这样每互换一次, 最大的元素就会放在堆的后面 (已经从堆中删除, 不属于堆了), 堆后面的元素会保持顺序, 直到堆中只剩一个元素为止 swap(a, 0, i); percolateDown(a, 0, i); } } /** * 下滤操作: 调整某个节点的位置, 以保持堆序 * @param a 待排序序列 * @param i 要调整的节点在数组中的索引 * @param n 堆的大小 (堆中元素个数) */ private static <AnyType extends Comparable<? super AnyType>> void percolateDown(AnyType[] a, int i, int n) { int child; AnyType tmp; // tmp记录被调整元素的值, i的值随 child不断改变, 直到比较完所有的子节点 (leftChild(i) < n) 为止 for (tmp = a[i]; leftChild(i) < n; i = child) { child = leftChild(i); // child == n - 1时, 其左子节点为堆的最后一个元素, 没有右节点, 无须比较 // 将该节点与其左右节点比较, 记录其中最小的节点的索引 if (child != n - 1 && a[child].compareTo(a[child + 1]) < 0) { child++; } // 将需要被调整和节点与其子节点进行比较, 如果小于子节点, 当前节点的值替换为子节点的值 (注意不是交换) if (tmp.compareTo(a[child]) < 0) { a[i] = a[child]; } else { break; } } // 找到合适的位置后, 直接赋值来避免多余的交换操作 a[i] = tmp; } /** * 获取某个节点的左子节点在数组中的索引, 因为是从 0开始的, 所以要 +1 */ private static int leftChild(int i) { return 2 * i + 1; } /** * 交换数组中两个元素的位置 */ public static <AnyType extends Comparable<? super AnyType>> void swap(AnyType[] arr, int i, int j) { if (arr == null || arr.length <= 1 || i == j) { return; } AnyType tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } }
Java排序算法 [堆排序]
猜你喜欢
转载自blog.csdn.net/dom4j_/article/details/79825085
今日推荐
周排行