用堆排序实现大致已经排好序的序列
2017-02-13 00:33
155 查看
已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过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+1个数,从0开始,每组内进行建堆,建完最小堆之后最前面的元素就是最小值。之后下标加1,继续进行堆排序,时间复杂度可以达到(log(n+k))空间复杂度为O(1)因为使用循环实现最小堆,没用调用栈。不稳定排序。
代码如下:
给定一个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+1个数,从0开始,每组内进行建堆,建完最小堆之后最前面的元素就是最小值。之后下标加1,继续进行堆排序,时间复杂度可以达到(log(n+k))空间复杂度为O(1)因为使用循环实现最小堆,没用调用栈。不稳定排序。
代码如下:
class ScaleSort { public: vector<int> sortElement(vector<int> A, int n, int k) { if(n<2) return A; int i=0; for(;i+k<n;++i) { buildheap(A,i,k+1); } while(n-i>1) { buildheap(A,i,n-i); i++; } return A; // write code here } void buildheap(vector<int> &A,int begin,int k) { if(k<2) return; if(A[(k-2)/2+begin]>A[k-1+begin]) swapnum(A[(k-2)/2+begin],A[k-1+begin]); if(k%2==1){ if(A[(k-2)/2+begin]>A[k-2+begin]) swapnum(A[(k-2)/2+begin],A[k-2+begin]); } for(int i=(k-4)/2;i>=0;--i) { if(A[i+begin]>A[2*i+1+begin]) swapnum(A[i+begin],A[2*i+1+begin]); if(A[i+begin]>A[2*i+2+begin]) swapnum(A[i+begin],A[2*i+2+begin]); } } void swapnum(int &a,int &b) { int temp; temp=a; a=b; b=temp; } };
相关文章推荐
- 经过一周的挣扎,目前天气预报抓取解析插入数据库的功能已经大致实现,附项目源码
- 在Delphi中用拼音首字符序列来实现检索功能
- 非递归实现不重复序列的全排列(一)
- 如何查看已经安装好的系统的序列号
- 使用拼音首字母序列实现检索功能
- seam2中实现fckEditor出错:jboss4.2.1已经不再支持myFaces
- Delphi用拼音首字符序列实现检索功能
- C# 实现常用的算法-- 堆排序(转)
- oracle实现自增长序列(主键)
- oracle 字段自动编号——触发器实现,非调用序列方法
- 非递归实现不重复序列的全排列(一)
- XHTML 的一个实例, 其实这个实例的方法已经可以实现所有要实现的布局. by Emerald 绿色学院 - Green Institute
- 最大堆及堆排序的实现
- 应用ajax实现检测注册用户名是否已经存在
- 序列模式分析算法GSP的实现
- 非递归实现不重复序列的全排列(二)
- 非递归实现不重复序列的全排列(三)
- 在Delphi中用拼音首字符序列来实现检索功能
- 直接插入排序、快速排序和堆排序的C实现
- seam2中实现fckEditor出错:jboss4.2.1已经不再支持myFaces