堆排序

一--大顶堆和小顶堆

节点的值大于或等于左右孩子节点的值叫大顶堆,节点的值小于或等于其左右孩子的值叫做小顶堆。

大顶堆: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     }
原文地址:https://www.cnblogs.com/YXBLOGXYY/p/14281194.html