排序-堆排序

排序-堆排序

排序必备知识

  1. 什么是大顶堆和小顶堆
    • 大顶堆,根节点比左节点和右结点都大(用作升序排序)
    • 小顶堆,根节点比左节点和右结点都小(用作降序排序)
  2. 堆排序的思想
    • 根据是降序或升序排序构建大顶堆还是小顶堆
    • 排序思想就是,每次从非空节点下标(i,根据当前未排序长度确定的,i = (未排序长度/2) - 1)开始到下标为0的去构建大顶推或者小顶堆
      • 堆构建的过程,我们首先找到该下标得右结点(右结点下标2*i+2,这里需要做判断,是否有右结点也就是右结点是否已经排序),比较,替换
      • 然后找到左子节点,比较,替换
      • 时候i–继续重复,直到i为0
    • 当下标i为0时,说明一趟结束,下标为0和下标最后一个(这里是动态变化,每一趟之后,最后一个下标就会减一)交换
    • 未排序数列的长度减一
    • 当未排序数列的长度为1时,结束排序

下面贴上大顶推和小顶推的排序实现

1、小顶堆排序java实现

public static void dumpSort(int[] arr) {
		//当arr为空或者长度小于2的时候不需要排序,直接返回
        if (arr.length <= 1) return;
        for (int j = arr.length; j > 1; j--) {
            //1、找到第一个非空的节点的下标
            for (int i = j / 2 - 1; i >= 0; i--) {
                //2、有可能没有右结点或者右结点已经排序
                //2.1、若有右结点
                int r = i * 2 + 2;
                if (r < j) {
                    //2.2、右结点和根节点比较
                    if (arr[r] < arr[i]) {
                        arr[i] = arr[i] ^ arr[r];
                        arr[r] = arr[i] ^ arr[r];
                        arr[i] = arr[i] ^ arr[r];
                    }
                }
                //3、根节点和左节点比较
                int l = i * 2 + 1;
                if (arr[l] < arr[i]) {
                    arr[i] = arr[i] ^ arr[l];
                    arr[l] = arr[i] ^ arr[l];
                    arr[i] = arr[i] ^ arr[l];
                }
            }
            //4、一趟结束后,找到最小值,沉到二叉树的最下面,交换值
            arr[0] = arr[0] ^ arr[j - 1];
            arr[j - 1] = arr[0] ^ arr[j - 1];
            arr[0] = arr[0] ^ arr[j - 1];

        }
    }

  1. 大顶堆排序java实现
 public static void bigDumpSort(int[] arr) {
        if (arr == null || arr.length <= 1) {
            return;
        }
        for (int i = arr.length; i > 1; i--) {
            //1、每一趟构建堆
            //j = i / 2 - 1计算非空节点下标,
            int r;
            int l;
            for (int j = i / 2 - 1; j >= 0; j--) {
                //2、从非空节点下标开始构建堆
                //2.1、找到节点的右子结点
                r = 2 * j + 2;
                //2.2、判断是否存在右子节点或者右子节点
                if (r < i) {//存在
                    //2.3、比较根节点和右结点
                    if (arr[r] > arr[j]) {
                        arr[j] = arr[j] ^ arr[r];
                        arr[r] = arr[j] ^ arr[r];
                        arr[j] = arr[j] ^ arr[r];
                    }
                }
                //3、一定存在左节点,比较左节点
                l = 2 * j + 1;
                if (arr[l] > arr[j]) {
                    arr[j] = arr[j] ^ arr[l];
                    arr[l] = arr[j] ^ arr[l];
                    arr[j] = arr[j] ^ arr[l];
                }
            }
            //4 一趟结束,交换下标为0和下标最后一个元素
            arr[0] = arr[0] ^ arr[i - 1];
            arr[i- 1] = arr[0] ^ arr[i - 1];
            arr[0] = arr[0] ^ arr[i - 1];
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值