堆排复习:
结论:堆排算法时间复杂度为O(nlgn),额外空间复杂度为O(1);
在开始堆排序过程之前先要熟悉两个结构
1,完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。(摘自百度百科)
大白话:说白了就是建立二叉树的过程中,二叉树每一层都是满节点的,最后一层的节点不许中间有空缺;
2,大根堆:大根堆要求根节点的关键字既大于或等于左子树的关键字值,又大于或等于右子树的关键字值。(摘自百度百科)
大白话:就是在此堆中,任意子树的根节点都是此子树的最大值;
堆排序核心思想:先将无序数组建立大根堆,然后将根节点和二叉树中最后一个节点互换,二叉树Size--,然后重新建立大根堆,然后将根节点和二叉树的最后一个节点互换,然后Size--,如此,一直到二叉树的size=0,此时数组自然已经排好序;
堆排序Java实现如下:
1 package com.cmbc.test1; 2 3 import java.util.Arrays; 4 5 public class HeapSortion { 6 7 8 public static void heapSort(int[] arr){ 9 if(arr==null||arr.length<2){ 10 return; 11 } 12 //建立大根堆 13 for(int i = 0;i<arr.length;i++){ 14 heapInsert(arr,i); 15 } 16 //建立完大根堆之后,二叉树的size和数组长度是一致的; 17 int size = arr.length; 18 swap(arr,0,--size); 19 while(size>0){ 20 heapify(arr,0,size); 21 swap(arr,0,--size); 22 } 23 } 24 25 public static void heapInsert(int[] arr,int index){ 26 while(arr[index]>arr[(index-1)/2]){ 27 swap(arr,index,(index-1)/2); 28 index = (index-1)/2; 29 } 30 } 31 32 public static void swap(int[] arr, int i, int j) { 33 int tmp = arr[i]; 34 arr[i] = arr[j]; 35 arr[j] = tmp; 36 } 37 38 39 public static void printArray(int[] arr) { 40 if (arr == null) { 41 return; 42 } 43 for (int i = 0; i < arr.length; i++) { 44 System.out.print(arr[i] + " "); 45 } 46 System.out.println(); 47 } 48 49 public static void heapify(int[] arr,int index,int size){ 50 int left = 2*index+1; 51 while(left<size){ 52 int largest = left+1<size&&arr[left+1]>arr[left]?left+1:left; 53 largest = arr[largest]>arr[index]?largest:index; 54 if(largest==index){ 55 break; 56 } 57 swap(arr,largest,index); 58 index = largest; 59 left = largest*2+1; 60 } 61 } 62 63 public static boolean isEqual(int[] arr1, int[] arr2) { 64 if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) { 65 return false; 66 } 67 if (arr1 == null && arr2 == null) { 68 return true; 69 } 70 if (arr1.length != arr2.length) { 71 return false; 72 } 73 for (int i = 0; i < arr1.length; i++) { 74 if (arr1[i] != arr2[i]) { 75 return false; 76 } 77 } 78 return true; 79 } 80 81 public static int[] generateRandomArray(int maxSize, int maxValue) { 82 int[] arr = new int[(int) ((maxSize + 1) * Math.random())]; 83 for (int i = 0; i < arr.length; i++) { 84 arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random()); 85 } 86 return arr; 87 } 88 89 public static int[] copyArray(int[] arr) { 90 if (arr == null) { 91 return null; 92 } 93 int[] res = new int[arr.length]; 94 for (int i = 0; i < arr.length; i++) { 95 res[i] = arr[i]; 96 } 97 return res; 98 } 99 100 public static void main(String[] args) { 101 int testTime = 500000; 102 int maxSize = 100; 103 int maxValue = 100; 104 boolean succeed = true; 105 for (int i = 0; i < testTime; i++) { 106 int[] arr1 = generateRandomArray(maxSize, maxValue); 107 int[] arr2 = copyArray(arr1); 108 heapSort(arr1); 109 Arrays.sort(arr2); 110 if (!isEqual(arr1, arr2)) { 111 succeed = false; 112 break; 113 } 114 } 115 System.out.println(succeed ? "正确!" : "请仔细检查"); 116 117 int[] arr = generateRandomArray(maxSize, maxValue); 118 printArray(arr); 119 heapSort(arr); 120 printArray(arr); 121 } 122 123 }