首页 > 其他分享 >经典排序之堆排序

经典排序之堆排序

时间:2022-08-17 13:11:25浏览次数:68  
标签:arr 下标 int largest 堆排序 len 经典 排序 节点

堆排序思路

堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

二叉树的性质

已知父节点的下标,可以获取其子节点的下标

父节点下标为 i
左子树下标为 i x 2 + 1
右子树下标为 i x 2 + 2
例: i = 1 左为3 右为4
同理知道左右子树可以知道父节点下标。

思路

根据大顶堆可以知道,root节点大于所有节点为最大,那么我们可以将其移动数组最后一位,然后将 [0, n-1] 进行堆的构建 循环调用

代码展示

 public int[] sortArray(int[] arr) {
        int len = arr.length;
        // 初始化构建
        buildMaxHeap(arr, len);
        // 构建之后 0下标为数组最大值,for循环从最后一位开始,交换 然后重新构建
        for (int i = len - 1; i > 0; i--) {
            swap(arr, 0, i);
            len--;
            heapify(arr, 0, len);
        }
        return arr;
    }
    // 对半构建
    private void buildMaxHeap(int[] arr, int len) {
        for (int i = len >> 1; i >= 0; i--) {
            heapify(arr, i, len);
        }
    }

    private void heapify(int[] arr, int i, int len) {
        // len 为本次构建堆的数组长度
        // 获得父节点 左子树,右子树 下标位置
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int largest = i;
        // 左子树下标小于 数组长度 并且 左子树的值大于父节点 则改变largest 标识位
        if (left < len && arr[left] > arr[largest]) {
            largest = left;
        }
        // 右子树与左子树相同
        // 这里如果左子树时已经改变 则比较左右子树大小
        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }
        // 如果父节点标识为发生改变,则将标识为指向的位置与父节点进行交换,并重新构建
        if (largest != i) {
            swap(arr, i, largest);
            // 现在发生改变,则查看改变之后的位置的变化
            heapify(arr, largest, len);
        }
    }
    private void swap(int[] arr, int i, int j) {
        int next = arr[i];
        arr[i] = arr[j];
        arr[j] = next;
    }

标签:arr,下标,int,largest,堆排序,len,经典,排序,节点
From: https://www.cnblogs.com/Spoonblog/p/16594778.html

相关文章

  • Python 字典排序
    字典是“键-值对”的无序可变序列在实际运用中,对字典进行排序是一个比较常见的操作,主要用到了python内置函数sorted(),该函数可以对所有可迭代的对象进行排序操作。语法(pyth......
  • 排序算法
    1. 排序算法面试中 面试高频又快排、堆排和归并排序先说快排,快排体现的的思想是:分而治之,并且递归 怎么个分呢,选第一个数进行强行将数据分成两拨。此时需要一个函......
  • 排序(王道考研,自用)
    插入排序,折半插入排序,希尔排序冒泡排序快速排序选择排序堆排序归并排序基数排序常考稳定:插入排序,折半插入排序,冒泡排序,归并排序,基数排序不稳定:希尔排序,选择排......
  • antd-vue table 表头同时存在sorter,Slots 排序升序失效“”解决“”
     产品给出的需求是这个客户数同时有提示跟升序于是乎我用了 Slots自定义表头但是发现排序只能降序无法升序 后来发现是排序的事件绑定到了自定义表头上面去了 ......
  • js插入排序
    **插入排序**插入排序主要是将需要排序的数组分为两部分,取第一个元素作为已排序数组,其余元素作为未排序数组,依次取未排序数组的元素和已排序数组中的元素进行对......
  • WebGPU的计算着色器实现冒泡排序
    大家好~本文使用WebGPU的计算着色器,实现了奇偶排序。奇偶排序是冒泡排序的并行版本,在1996年由JKornerup提出。它解除了每轮冒泡间的串行依赖以及每轮冒泡内部的串行依赖,......
  • mysql组内排序-rank()、dense_rank()、row_number()
    1.row_number():计算当前行在分区中的行数2.dense_rank():统计当前行所在分区的排名,排名是连续的,没有间隙,3.rank():统计当前行所在分区的排名,排名是非连续的,有间隙。4.......
  • 接口测试经典面试题:Session、cookie、token有什么区别?
    原文链接HTTP是一个没有状态的协议,这种特点带来的好处就是效率较高,但是缺点也非常明显,这个协议本身是不支持网站的关联的,比如https://ceshiren.com/和https://ceshiren.co......
  • 排序算法-冒泡、选择、堆、插入、归并、快速、希尔
    排序算法,默认是升序,左边的值是属于“小”值理解比较大小后的交换:当前元素cur和左边的元素cur-1,左边的比较大,就交换或者挪动array[cur]=array[cur-1];编码的区......
  • 合并两个排序的链表
    目录题目描述解题思路解题代码题目描述题目地址:http://mtw.so/6r71s0题目要求:输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的......