排序算法_堆排序

排序算法_堆排序


首先要理解什么是堆,简单的说堆就是个数组,假设有一个数组:[1,2,3,4,5],
那么抽象成一个堆就是这个样子滴:
在这里插入图片描述
下标为0位置的作为根,这样每一个子树根部都是最小值的情况,称这个树为小根堆,相反,如果每一个子树的根节点都是最大值,就是大根堆,
  假设现在根位置的值变为9,即数组为[9,1,2,3,4,5]:那么从小到大排的顺序应该是[1,2,3,4,5,9].写一个循环,假设循环从0开始,那么需要比较下标为2 i+1和2i+2位置的值谁比较小,比较小的值和下标为i的值进行交换,重复这个过程,最终最小值排列到下标为0的位置,下面是具体的实现:

public static void heapSort(int[] arr) {
        if (null == arr || arr.length < 2) {
            return;
        }
        //建立大根堆
        for (int i = 0; i < arr.length; i++) {
            heapInsert(arr, i);
        }
        int heapSize = arr.length;
        swap(arr,0,--heapSize);
        //堆调整排序
        while (heapSize > 0) {
            //再次形成大根堆
            heapify(arr,0,heapSize);
            swap(arr,0,--heapSize);
        }
    }

    public static void heapInsert(int[] arr, int index) {
        //如果当前节点的值比父节点大,那么就和父节点交换
        while (arr[index] > arr[(index - 1) / 2]) {
            swap(arr, index, (index - 1) / 2);
            index = (index - 1) / 2;
        }
    }

    public static void heapify(int[] arr, int index, int heapSize) {
        int left = index * 2 + 1;
        while (left < heapSize) {
            int largest = left + 1 < heapSize && arr[left + 1] > arr[left]
                    ?left + 1:left;

            largest = arr[largest] > arr[index]?largest:index;
            if (largest == index) {
                break;
            }
            swap(arr,largest,index);
            index = largest;
            left = index * 2 +1;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
选择排序算法: 1. 从数组中选择最小的元素,将其放置在数组的起始位置。 2. 在剩余的元素中选择最小的元素,将其放置在已排序元素的末尾。 3. 重复步骤2直到所有元素都已排序。 代码实现: ``` function selectionSort(arr) { for (let i = 0; i < arr.length - 1; i++) { let minIndex = i; for (let j = i + 1; j < arr.length; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } if (minIndex !== i) { [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; } } return arr; } ``` 堆排序算法: 1. 构建一个最大堆(或最小堆)。 2. 将堆顶元素与最后一个元素交换,然后将堆的大小减1。 3. 对新的堆顶元素进行堆化,重复步骤2和3直到堆的大小为1。 代码实现: ``` function heapSort(arr) { buildMaxHeap(arr); let heapSize = arr.length; for (let i = arr.length - 1; i > 0; i--) { [arr[0], arr[i]] = [arr[i], arr[0]]; heapSize--; maxHeapify(arr, 0, heapSize); } return arr; } function buildMaxHeap(arr) { const heapSize = arr.length; for (let i = Math.floor(heapSize / 2); i >= 0; i--) { maxHeapify(arr, i, heapSize); } } function maxHeapify(arr, i, heapSize) { const left = 2 * i + 1; const right = 2 * i + 2; let largest = i; if (left < heapSize && arr[left] > arr[largest]) { largest = left; } if (right < heapSize && arr[right] > arr[largest]) { largest = right; } if (largest !== i) { [arr[i], arr[largest]] = [arr[largest], arr[i]]; maxHeapify(arr, largest, heapSize); } } ``` 选择排序算法的时间复杂度为$O(n^2)$,堆排序算法的时间复杂度为$O(n\log n)$。虽然堆排序的时间复杂度比选择排序更优,但是堆排序的常数项较大,因此在实际应用中需要根据具体情况选择合适的排序算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值