一--大顶堆和小顶堆
节点的值大于或等于左右孩子节点的值叫大顶堆,节点的值小于或等于其左右孩子的值叫做小顶堆。
大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
代码:
1 public class HeapSort { 2 3 public static void main(String[] args) { 4 // 要求将数组进行升序排序 5 int arr[] = {4,6,8,5,9,-1,90,89,56,-999}; 6 heapSort(arr); 7 } 8 // 编写一个堆排序的方法 9 public static void heapSort(int arr[]) { 10 int temp = 0; 11 System.out.println("堆排序"); 12 13 // // 分步完成 14 // adjustHeap(arr, 1, arr.length); 15 // System.out.println("第一次调整" + Arrays.toString(arr));// 4,9,8,5,6 16 // 17 // adjustHeap(arr, 0, arr.length); 18 // System.out.println("第二次调整" + Arrays.toString(arr));// 9 6,8,5,4 19 20 // 完成最终代码 21 // 1)将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆。 22 for(int i = arr.length / 2 - 1; i >= 0; i--) { 23 adjustHeap(arr, i, arr.length); 24 } 25 System.out.println("调整为大顶堆" + Arrays.toString(arr)); 26 // 2)交换堆顶和末尾元素,将最大元素沉到数组末端 27 // 3)重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素。 28 for(int j = arr.length - 1; j > 0; j--) { 29 // 交换 30 temp = arr[j]; 31 arr[j] = arr[0]; 32 arr[0] = temp; 33 adjustHeap(arr, 0, j); 34 } 35 System.out.println("数组=" + Arrays.toString(arr)); 36 37 } 38 39 // 将一个数组(二叉树)。调整成一个大顶堆 40 /* 41 功能:完成将以i对应的非叶子结点的树调整成大顶堆 42 arr 待调整的数组 43 i 表示非叶子节点在数组中的索引 44 length 表示对多少个元素进行调整,length是在逐渐减少。 45 46 */ 47 public static void adjustHeap(int arr[], int i,int length) { 48 int temp = arr[i]; // 先取出当前元素的值,保存在临时变量 49 // 开始调整 50 // k = i * 2 + 1 k是i节点的左子节点 51 for(int k = i * 2 + 1; k < length; k = k * 2 + 1) { 52 if(k+1 < length && arr[k] < arr[k+1]) { // 说明左子节点的值小于右子结点的值 53 k++; // 让k指向右子结点 54 } 55 if(temp < arr[k]) { // 如果子结点大于父节点 56 arr[i] = arr[k]; // 把较大的值赋 给当前结点 57 i = k; // i指向k,持续循环比较 58 } 59 else { 60 break; // 61 } 62 } 63 // 当for循环结束后,我们已经将以i为父节点的树的最大值,放在了最顶上。(局部) 64 arr[i] = temp; // 将temp值放到调整后的位置 65 }