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