• 堆排序


    一--大顶堆和小顶堆

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

    大顶堆: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     }
  • 相关阅读:
    关于异步IO与同步IO的写操作区别
    慢慢开始记录一些技术心得吧
    写了placement new就要写placement delete
    关于针对class自定义new操作符失败的函数处理
    operator->和operator->*
    关于继承中的拷贝构造函数
    关于g++编译模板类的问题
    关于互斥锁,条件变量的内核源码解析
    关于sigwait
    观察者设计模式
  • 原文地址:https://www.cnblogs.com/YXBLOGXYY/p/14281194.html
Copyright © 2020-2023  润新知