常见排序算法-----堆排序
1 // 堆排序,升序用最大堆,降序用最小堆 2 /* 3 * 思路: 将数组构建成一个最大堆,从最后一个非叶子节点开始,将它和它的左右子节点中最大的节点相比较 4 * 如果子节点大则进行交换,再找倒数第二个非叶子节点,同理。 当到倒数第三个叶子节点时,若发生交换 5 * 则还应判断交换过后有没有对交换过的子节点发生影响,若有影响应进行调整。 6 * 7 * 自底向上建立堆,自顶向下调整堆 8 */ 9 10 public static void main(String[] args) { 11 HeapSort hs = new HeapSort(); 12 int[] arr = new int[] { 1, 4, 56, 2, 4, 6, 8, 9 }; 13 hs.heapSort(arr); 14 for (int i = 0; i < arr.length; i++) { 15 System.out.println(arr[i]); 16 } 17 } 18 19 public void heapSort(int[] arr) { 20 21 // 找到最后一个非叶子节点开始遍历,建立最大堆 22 for (int i = arr.length - 2 >> 2; i >= 0; i--) { 23 adjustHeap(arr, i, arr.length); 24 25 } 26 27 for (int i = arr.length - 1; i > 0; i--) { 28 // 此时已经建立好最大堆,最大值在最上方,将其与最后一个元素进行交换,即将最大的元素排除,寻找剩余元素中的最大值 29 swap(arr, 0, i); 30 // 交换后重新调整堆结构 31 adjustHeap(arr, 0, i); 32 } 33 34 } 35 36 public void swap(int[] arr, int i, int j) { 37 int temp = arr[i]; 38 arr[i] = arr[j]; 39 arr[j] = temp; 40 } 41 42 /** 43 * 调整是建立在 已经建立好最大堆的基础上 44 * 45 * @param arr 46 * @param i 47 * @param length 48 */ 49 public void adjustHeap(int[] arr, int i, int length) { 50 51 int temp = arr[i]; 52 for (int j = 2 * i + 1; j < length; j = j * 2 + 1) {// 从i节点的左子节点开始 53 if (j + 1 < length && arr[j] < arr[j + 1]) { // 如果存在右子节点,且右子节点大于左子节点 54 j++; // 如果是最小堆比较的是最小值 即条件改为 arr[j]>arr[j+1] j++ 55 } 56 if (arr[j] > temp) { // 如果最大的子节点大于父节点,交换(此处不需要交换直接赋值即可) //如果arr[j] 57 // <temp 进行交换 58 arr[i] = arr[j]; 59 i = j; 60 } else { 61 break; // 如果不大于说明不会对后面产生影响直接跳出循环 62 } 63 // 确定i最后所在的位置 将值赋予该位置 64 arr[i] = temp; 65 } 66 67 }
堆排序是一种不稳定排序,其中构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次,而重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)...1]逐步递减,近似为nlogn
详情 http://www.cnblogs.com/chengxiao/p/6129630.html