小范围排序(巧用堆排序) -- 算法小结

本文介绍了一种针对几乎有序数组的高效排序方法。该方法利用小根堆进行排序,通过维护一个大小为k的小根堆来逐步构建有序数组,适用于元素移动距离不超过k的情况。文章提供了完整的Java实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

给定一个int数组A,同时给定A的大小n和题意中的k,请返回排序后的数组。

测试样例:
[2,1,4,3,6,5,8,7,10,9],10,2
返回:[1,2,3,4,5,6,7,8,9,10]
编程思路:由于知道了使每个元素有序的移动在K的范围内 根据时间空间复杂度的比较 可以使用堆排序 借助一个辅助小根堆(k大小) 每次最小的元素 即在根 将小根堆后移一位 直至(n-k) 这时再利用缩小小根堆的长度 依次得到有序数即可

import java.util.*;

public class ScaleSort {
    public int[] sortElement(int[] A, int n, int k) {
        // write code here
        if(A==null||n<2||k==1){
            return A;
        }
        //定义  初始化小根堆
        int[] temHeap = new int[k];
        for(int i=0;i<k;i++){
            temHeap[i] = A[i];
        }
        for(int i=k/2-1;i>=0;i--){
            //建立小根堆 定义 k-1 防止越界
            buildMinHeap(temHeap,i,k-1);
        }
        //在0 - n-k (前n-k个数) 利用小根堆后移 依次得到有序数
        for(int i=0;i<n-k;i++){
            A[i] = temHeap[0];
            temHeap[0] = A[i+k];
            buildMinHeap(temHeap,0,k-1);
        }
        int kk=k-1;
        //最后k个数  利用小根堆的长度缩小得到
        for(int i=n-k;i<n;i++){
             A[i] = temHeap[0];
            change(temHeap,0,kk);
            buildMinHeap(temHeap,0,--kk);
        }
        return A;
    }
    public void buildMinHeap(int[] temHeap,int start,int end){
        if(end>start){
            int left = start*2+1;
            int right = start*2+2;
            int tem;
            if(left<=end&&temHeap[left]<temHeap[start]){
                tem = left;
            }else
                tem = start;
            if(right<=end&&temHeap[right]<temHeap[tem])
                tem = right;
            if(tem!=start){
                change(temHeap,start,tem);
                buildMinHeap(temHeap,tem,end);
            }
        }
    }
    public void change(int[] tem,int a,int b){
        if(a!=b){
        int temm = tem[a];
        tem[a] = tem[b];
        tem[b] = temm;
        }
    }
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值