堆排序
package com.bsc.algorithm.sort.heap; import com.bsc.algorithm.sort.inf.AbstractSort; /** * 堆排序 * @author bsc * * 一个长度为n的数组,将它看成一个完全二叉树的顺序存储结构 * 当n >= 2时,第i个元素代表非叶子结点,至少有一个孩子,i满足 0 <= i <= (n-2)/2 * 第i个元素的左孩子是:2i + 1(一定存在),右孩子是:2i + 2(当i=(n-2)/2时可能不存在) */ public class HeapSort<T extends Comparable<T>> extends AbstractSort<T> { /** * 把父结点parent以下的子结点中的最大值移到父结点上(parent以下的所有非叶子子结点要大于自己的孩子) * 父结点原值找到子结点合适位置替换 * @param data * @param parentIndex * @param length * @param cr */ private void heapAdjust(T[] data, int parentIndex, int length, int cr) { T parent = data[parentIndex]; int childIndex = 2 * parentIndex + 1; // 先获得左孩子 while (childIndex < length) { // 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点 /* data[childIndex] < data[childIndex + 1] */ if (childIndex + 1 < length && compare(data[childIndex + 1], data[childIndex]) == cr) { childIndex++; } // 如果父结点的值已经大于孩子结点的值,则直接结束 /* parent >= data[childIndex] */ if (compare(data[childIndex], parent) != cr){ break; } // 如果孩子结点大于父结点,把孩子结点的值赋给父结点 data[parentIndex] = data[childIndex]; // 选取孩子结点的左孩子结点,继续向下筛选 parentIndex = childIndex; childIndex = 2 * childIndex + 1; } data[parentIndex] = parent; } @Override protected void sort(T[] data, int cr) { int length = data.length; // 循环建立初始堆 // (data.length - 2) / 2 : 最大非叶子结点位置 for (int i = (length - 2) / 2; i >= 0; i--) { heapAdjust(data, i, length, cr); } // 进行n-1次循环,完成排序 for (int i = length - 1; i > 0; i--) { // 交换堆顶的元素和最后一个元素,此时最后一个位置作为有序区 swap(data, 0, i); // 然后进行其他无序区的堆调整,重新得到大顶堆后 heapAdjust(data, 0, i, cr); } } }
AbstractSort请参考排序接口与抽象类(java)
测试
ArrayGenerator请参考数组数据生成器
package com.bsc.algorithm.sort.test; import java.util.Arrays; import com.bsc.algorithm.data.generator.ArrayGenerator; import com.bsc.algorithm.sort.heap.HeapSort; import com.bsc.algorithm.sort.inf.ISort; import com.bsc.algorithm.sort.merge.MergeSort; public class SortTest { public static void main(String[] args) { ISort<Integer> sortInt = new HeapSort<Integer>(); Integer[] dataInt = ArrayGenerator.random(Integer[].class, 10, 0, 99); System.out.println("原序:" + Arrays.toString(dataInt)); sortInt.sortAsc(dataInt); System.out.println("升序:" + Arrays.toString(dataInt) + "\n"); dataInt = ArrayGenerator.random(Integer[].class, 10, 0, 99); System.out.println("原序:" + Arrays.toString(dataInt)); sortInt.sortDesc(dataInt); System.out.println("降序:" + Arrays.toString(dataInt) + "\n"); ISort<Character> sortChar = new HeapSort<Character>(); Character[] dataChar = ArrayGenerator.random(Character[].class, 10, 65, 90); System.out.println("原序:" + Arrays.toString(dataChar)); sortChar.sortAsc(dataChar); System.out.println("升序:" + Arrays.toString(dataChar) + "\n"); dataChar = ArrayGenerator.random(Character[].class, 10, 65, 90); System.out.println("原序:" + Arrays.toString(dataChar)); sortChar.sortDesc(dataChar); System.out.println("降序:" + Arrays.toString(dataChar) + "\n"); } }