最大堆排序
最大堆排序的核心在于根节点始终是该二叉树的最大值,这就引入了算法的第一部分:对于一棵初始二叉树,如何维护最大堆的性质——顶层根节点即是最大值?
数组构建二叉树?父亲节点是i的情况下,左右孩子分别是2*i,2*i+1,此处不再赘述;
为了满足根节点最大化,需要从根节点,左右孩子中选择一个最大值,当最大值替换原来根节点的同时,根节点向下移动;
此时,引入了算法的第二部分:为了产生当前二叉树的最大值根节点,就必须保证的一点是左右孩子应该是该节点所有孩子节点里边最大的,所以,建立最大堆应该自底向上进行;
经过上边的2个步骤,此时已经成功的建立了一个最大堆,那怎么进行排序呢?
此时回到最大堆的性质:根节点是最大的,这也就意味着,已经获取了该数组的最大值——理所应当的,最大值放置在数组最后一位,最后一位也就顺理成章的放到了第一位;
此时,我们需要做的就是再来一次建堆,然后找到第二大的数值,以此往复,第3大,第4大......第n大;
至此,最大堆排序算法概括完毕,详细步骤以及算法见如下代码。
1 /** 2 * 接受一个数组,利用最大堆排序算法实现排序,算法时间复杂度O(nlgn) 3 * 4 * @author http://www.cnblogs.com/Xuxy1996/p/8903538.html 5 * @author xuxy 6 * 7 */ 8 public class HEAPSORT { 9 /** 10 * 维护最大堆的性质——任意根节点要比孩子节点大;算法前提——孩子树满足最大堆性质 11 * 12 * @param array 13 * 接受的数组参数 14 * @param i 15 * 当前二叉树的根节点 16 * @param size 17 * 当前二叉树的大小——在堆排序算法中,将最大值赋值在数组最后边,此时需要将大小减一 18 */ 19 private static void MAX_HEAPIFY(int array[], int i, int size) { 20 int left = 2 * i; 21 int right = 2 * i + 1; 22 int max = i; 23 if (left < size && array[left] > array[i]) 24 max = left; 25 if (right < size && array[right] > array[max]) 26 max = right; 27 if (max != i) { 28 int tmp = array[i]; 29 array[i] = array[max]; 30 array[max] = tmp; 31 MAX_HEAPIFY(array, max, size); 32 } 33 } 34 35 /** 36 * 建立最大堆,画图简单判断大于size/2的都是非叶子节点,为了满足维护最大堆的前提条件——孩子树满足最大堆性质,所以 自底向上进行最大堆排序 37 * 38 * @param array 39 * 接受排序的数组 40 * @param size 41 * 当前数组的大小——该值随算法的进行,会进行变化 42 */ 43 private static void BUILD_MAX_HEAP(int[] array, int size) { 44 for (int i = size / 2; i >= 0; i--) 45 MAX_HEAPIFY(array, i, size); 46 } 47 48 /** 49 * 算法核心所在——最大堆排序的实施步骤 在最大堆中,根节点(数组的第一个值)即是最大值,自然的,需要把它放在数组最后边, 50 * 此时,最后边的数值便是放在第一个位置,这时候为了满足最大堆的性质,再一次进行建立最大堆 51 * 52 * @param array 53 * 待排序数组 54 * @return 通过最大堆排序算法进行排序之后的数组 55 */ 56 public static int[] HEAP_SORT(int array[]) { 57 int size = array.length; 58 for (int i = array.length - 1; i >= 0; i--) { 59 BUILD_MAX_HEAP(array, size); 60 int tmp = array[0]; 61 array[0] = array[i]; 62 array[i] = tmp; 63 size -= 1; 64 ;// 舍弃原本的最大值 65 } 66 return array; 67 } 68 69 /** 70 * 测试方法,用于基本的数据输入以及发送信息,实现算法的开始 71 * 72 * @param args 73 */ 74 public static void main(String[] args) { 75 Scanner sc = new Scanner(System.in); 76 int n = sc.nextInt(); 77 int array[] = new int[n]; 78 for (int i = 0; i < n; i++) 79 array[i] = sc.nextInt(); 80 HEAP_SORT(array); 81 for (int i : array) 82 System.out.print(i + " "); 83 System.out.println(); 84 } 85 }
测试数据:
未完待续......