几乎有序的数组排序-每个元素的移动距离不超过k

 
 

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

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

可采用的方法:1. 插入排序

                         2. 堆排序

本文中采用方法2实现:

1)建立一个大小为k的小根堆,并取堆顶元素保存到原数组中。

2)依次加入数组中的后一个元素并对堆结构进行调整,始终维持大小为k的小根堆。

3)采用普通堆排序的方法将最后k个元素排序并保存到原数组中。

 
 
class ScaleSort {
public:
    vector<int> sortElement(vector<int> A, int n, int k) {
        int heap[k];
        //建立大小为k的数组维护大小为k的小根堆
        for(int i=0; i<k; i++)
            heap[i] = A[i];
        
        for(int i=k/2-1; i>=0; i--) //建立初始堆
            heapAdjust(heap, i, k);
        
        for(int i = k; i<n; i++) //将堆顶元素赋给A,维护大小为k的堆
        {
            A[i-k] = heap[0];
            heap[0] = A[i];
            heapAdjust(heap, 0, k);
        }
        //后k个元素采用正常堆排序的方式得到并赋给A        
        for(int i = n-k; i<n; i++)
        {
            A[i] = heap[0];
            swap(heap[0], heap[k-1]);
            heapAdjust(heap, 0, --k);
        }
        
        return A;
    }
    void heapAdjust(int* heap, int p, int n)
    {
        int cur = heap[p];
        while(p*2+1<n)
        {
            int child = p*2+1;
            if(child+1<n && heap[child]>heap[child+1]) child++;
            if(heap[child]<cur)
            {
                heap[p] = heap[child];
                p = child;
            }
            else break;
        }
        heap[p] = cur;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_24153697/article/details/79607333