您的位置:首页 > 其它

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

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


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序算法 排序