小范围排序(堆排序)

题目:
已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过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]

基本思想:
1. 依题目可知如果将数组分成n/k个序列,这个n/k个序列看成一个整体话,这个N/k个整体前面的数的最大值应该小于后面那个整体的最小值,即N个整体应该是有序的。
2. 故可以先取前面k个数建立一个最小堆。对后面n-k个数依次加入最小堆,取最小堆的堆顶值之后,维护堆。
3. 这样可以得到数组中排序的前面n-k个数。之后把最后最小堆的k个数加入数组,则可以得到排序的整个数组。

代码如下:

class ScaleSort {
public:
    vector<int> sortElement(vector<int> A, int n, int k) {
        // write code here
       vector<int> B(k);
       for(int i=0;i<k;i++)
            B[i]=A[i];
       for(int i=k/2-1;i>=0;--i)//维护一个k个数的最小堆
            MinHeapAdjust(B,i,k);
        for(int i=k;i<n;++i)//取出数组前面最小的n-k个数
        {
           A[i-k]=B[0];//取出最小值,依次赋值给A数组
           B[0]=A[i];
           MinHeapAdjust(B,0,k);
        }
        for(int i=n-k; i<n; i++)//后面的k个数即是数组的最大的k个数
        {
            A[i] = B[0];
            int temp = B[k-1];
            B[k-1] = B[0];
            B[0] = temp;            
            MinHeapAdjust(B,0,--k);
        }
        return A;
    }
    void MinHeapAdjust(vector<int> &A,int parent,int nLength)
    {
        int temp;
        int child;
        for(;2*parent+1<nLength;parent=child)
        {
            child=2*parent+1;
            if(child+1<nLength&&A[child+1]<A[child]) ++child;
            if(A[parent]>A[child])
            {
                int temp=A[parent];
                A[parent]=A[child];
                A[child]=temp;
            }
            else break;
        }                  
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值