算法基础入门 - 9、复杂排序算法-堆排序

堆排序

什么是堆排序?

1、先让整个数组都变成大(小)根堆结构
2、把堆的最大值和堆末尾的值交换,减少堆的大小。再去调整堆。
3、堆的大小减为0之后,排序完成。时间复杂度O(n*logn)

堆排序的练习题:

已知一个几乎有序的数组,请选择一个合适的排序算法针对这个数据进行排序。
几乎有序:如果吧数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。

首先是Java版本的解法:

package com.leftGod;

import java.util.Arrays;
import java.util.PriorityQueue;

/**
 *
 * 已知一个几乎有序的数组,请选择一个合适的排序算法针对这个数据进行排序。
 *
 * @author zhao.hualuo
 * Create at 2022/4/4
 */
public class JavaNearSortProblem {

    public static int[] heapSort(int[] arr, int k) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(k);
        int[] result = new int[arr.length];
        int resultIndex = 0;

        for (int i = 0; i < arr.length;) {
            //将数组元素保存在优先级队列里
            while (priorityQueue.size() <= k) {
                priorityQueue.add(arr[i++]);
            }
            //将堆的第一个元素弹出(最小值)
            result[resultIndex++] = priorityQueue.poll();
        }

        //把 堆的头 一个个弹出
        while (!priorityQueue.isEmpty()) {
            result[resultIndex++] = priorityQueue.poll();
        }
        return result;
    }

    public static void main(String[] args) {
        int[] arr = {2,1,4,3,6,5,8,7,10,9,11,12,14,13,12};
        int[] result = heapSort(arr, 3);
        System.out.println(Arrays.toString(result));
    }
}

下面是自定义堆结构的解法:

package com.leftGod;

import java.util.Arrays;

/**
 * 已知一个几乎有序的数组,请选择一个合适的排序算法针对这个数据进行排序。
 *
 * @author zhao.hualuo
 * Create at 2022/4/4
 */
public class NearSortProblem {

    /**
     * 堆排序
     *
     * @param arr 数组
     * @param k 变量
     * @return 排好序的数组
     */
    public static int[] heapSort(int[] arr, int k) {
        //声明一个堆数组
        int heapSize = 0;
        int[] heapArr = new int[k];

        int resultIndex = 0;
        int[] result = new int[arr.length];

        //遍历原数组
        int arrIndex = 0;
        while (arrIndex < arr.length) {
            //通过heapInsert生成堆
            while (heapSize < k) {
                heapArr[heapSize] = arr[arrIndex];
                heapInsert(heapArr, heapSize);
                heapSize++;
                arrIndex++;
            }

            //堆满了,把最小的元素拿出来
            result[resultIndex++] = heapArr[0];
            swap(heapArr, 0, --heapSize);
            //移除最小值后,重新调整堆结构
            heapify(heapArr, 0, heapSize);
        }

        while (heapSize > 0) {
            result[resultIndex++] = heapArr[0];
            swap(heapArr, 0, --heapSize);
            heapify(heapArr, 0, heapSize);
        }
        return result;
    }

    private static void heapInsert(int[] arr, int index) {
        while ((index-1)/2 >=0 && 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 leftIndex = index*2+1;
        while (leftIndex < heapSize) {
            int minIndex = leftIndex+1 < heapSize && arr[leftIndex+1] < arr[leftIndex] ? leftIndex+1 : leftIndex;
            if (arr[minIndex] > arr[index]) {
                break;
            }

            swap(arr, index, minIndex);
            index = minIndex;
            leftIndex = index*2+1;
        }
    }

    /**
     * 交换数组下标上的值
     *
     * @param arr 数组
     * @param left 下标1
     * @param right 下标2
     */
    private static void swap(int[] arr, int left, int right) {
        if (left == right) {
            return;
        }
        arr[left] = arr[left] ^ arr[right];
        arr[right] = arr[left] ^ arr[right];
        arr[left] = arr[left] ^ arr[right];
    }

    public static void main(String[] args) {
        int[] arr = {2,1,4,3,6,5,8,7,10,9,11,12,14,13,12};
        int[] result = heapSort(arr, 3);
        System.out.println(Arrays.toString(result));
    }
}

若上面有看不懂的概念,请参照我的上一篇博客《算法基础入门 - 8、复杂排序算法-堆结构介绍+自定义堆+java堆

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值