/** * Introduction to Algorithms, Second Edition * 6.4 HEAPSORT * @author 土豆爸爸 * */ public class HeapSort { int[] array; int heapSize; public void sort(int[] array) { this.array = array; buildMaxHeap(); for (int i = array.length - 1; i > 0; i--) { //将最大值array[0]放在最后 int temp = array[0]; array[0] = array[i]; array[i] = temp; heapSize--; //重排,把最大值放在array[0] maxHeapify(0); } } /** * 构建max heap * */ private void buildMaxHeap() { heapSize = array.length; for (int i = array.length / 2; i >= 0; i--) { maxHeapify(i); } } /** * 使数组的第i个元素按max heap规则重排 * @param i * 元素索引 */ private void maxHeapify(int i) { int l = left(i); int r = right(i); int largest; // 当前结点/左子结点/右子结点中最大值的索引 if (l < heapSize && array[l] > array[i]) { largest = l; } else { largest = i; } if (r < heapSize && array[r] > array[largest]) { largest = r; } if (largest != i) { // 如果最大值不是当前结点,进行交换 int temp = array[i]; array[i] = array[largest]; array[largest] = temp; // 递归调用,直到当前结点比其子结点大 maxHeapify(largest); } } /** * 计算结点索引为i的元素的左子结点的索引 * @param i * 当前索引 * @return 左子结点的索引 */ private int left(int i) { return 2 * i + 1; } /** * 计算结点索引为i的元素的右子结点的索引 * @param i * 当前索引 * @return 右子结点的索引 */ private int right(int i) { return 2 * i + 2; } } import junit.framework.TestCase; public class HeapSortTest extends TestCase { public void testFixArray() { int[] array = { 5, 2, 4, 6, 1, 3 }; HeapSort heapSort = new HeapSort(); heapSort.sort(array); assertTrue(verifyOrdered(array)); } public void testRandomArray() { int size = (int)(Math.random()* 1000); int[] array = new int[size]; for(int i = 0; i < size; i++) { array[i] = (int)(Math.random()* 10000); } HeapSort heapSort = new HeapSort(); heapSort.sort(array); assertTrue(verifyOrdered(array)); } private boolean verifyOrdered(int[] array) { for (int i = 1; i < array.length; i++) { if (array[i - 1] > array[i]) { return false; } } return true; } }
算法导论示例-HeapSort
最新推荐文章于 2023-05-02 21:27:27 发布