您的位置:首页 > 编程语言 > Java开发

bfprt算法----找出数组中最小的k个数(Java)

2015-10-26 19:23 579 查看

无序数组中最小的k个数

对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的k个数。

给定一个整数数组A及它的大小n,同时给定k,请返回其中最小的k个数。

测试样例:
[1,2,4,3],4,2

返回:[1,2]


(1)利用堆,时间复杂度O(Nlogk)

public class Main {

public static void main(String[] args) {

Main test = new Main();

int[] a={3188,4522,2526,4085,1621,723,1073};

int[] b=new int[6];

b=test.findKthNumbers(a,7,6);

System.out.println(b[0]);

System.out.println(b[1]);

System.out.println(b[2]);

System.out.println(b[3]);

System.out.println(b[4]);

System.out.println(b[5]);

}

public int[] findKthNumbers(int[] A, int n, int k) {

if(A==null||n<=k||k<1){

return A;

}

int[] result=new int[k];

heapSort(A,result,k);

for(int i=k;i<n;i++){

if(A[i]<result[0]){

heapModify(result,A[i]);

}

}

return result;

}

public void heapSort(int[] arr,int[] result,int k){

result[0]=arr[0];

for(int i=0;i<k;i++){

result[i]=arr[i];

int index=i;

int parent=(i-1)/2;

while(parent>=0&&result[parent]<result[index]){

swap(result,parent,index);

index=parent;

parent=(parent-1)/2;

}

}

}

public void heapModify(int[] arr,int key){

arr[0]=key;

int k=arr.length;

int index=0;

int child=(index+1)*2-1;

if(child+1<k){

child=arr[child]>=arr[child+1]?child:child+1;

}

while(child<k&&arr[index]<arr[child]){

swap(arr,index,child);

index=child;

child=(child+1)*2-1;

if(child+1<k){

child=arr[child]>=arr[child+1]?child:child+1;

}

}

}

public void swap(int[] arr,int i,int j){

int temp;

temp=arr[i];

arr[i]=arr[j];

arr[j]=temp;

}

}

(2) 利用快排

public class Main {

public static void main(String[] args) {

Main test = new Main();

int[] a={3188,4522,2526,4085,1621,723,1073};

int[] b=new int[6];

b=test.findKthNumbers(a,7,6);

System.out.println(b[0]);

System.out.println(b[1]);

System.out.println(b[2]);

System.out.println(b[3]);

System.out.println(b[4]);

System.out.println(b[5]);

}

public int[] findKthNumbers(int[] input, int n, int k) {

if(input==null||n<=k||k<1){

return input;

}

int[] result=new int[k];

int start=0,end=input.length-1,key,i,j;

while(end!=k-1){

key=input[start];

i=start;

j=end;

while(i<j){

while(i<j&&input[j]>=key){

j--;

}

input[i]=input[j];

while(i<j&&input[i]<=key){

i++;

}

input[j]=input[i];

}

input[i]=key;

if(i==k-1) break;

if(i>k-1)end=i-1;

else start=i+1;

}

for(i=0;i<k;i++){

result[i]=input[i];

}

return result;

}

}

(3)bfprt 时间复杂度O(n)

public class Main {

public static void main(String[] args) {

Main test = new Main();

int[] a={3188,4522,2526,4085,1621,723,1073};

int[] b=new int[6];

b=test.findKthNumbers(a,7,6);

System.out.println(b[0]);

System.out.println(b[1]);

System.out.println(b[2]);

System.out.println(b[3]);

System.out.println(b[4]);

System.out.println(b[5]);

}

public int[] findKthNumbers(int[] A, int n, int k) {

if(A==null||n<=k||k<1){

return A;

}

int[] result=new int[k];

int key;

int j=0;

key=findK(A,0,n-1,k);//找到第k小数的值;

for(int i=0;i<n;i++){

if(A[i]<key){

result[j++]=A[i];

}

}

while(j!=k){

result[j++]=key;

}

return result;

}

public int findK(int[] arr,int start,int end,int k){

int key;

int[] index=new int[2];

key=selectKey(arr,start,end);//找中位数。

index=quickSort(arr,start,end,key);//以中位数为基准,快速排序。

if(index[0]<=k-1&&k-1<=index[1]){

return arr[index[0]];

}

else if(index[0]>k-1){

return findK(arr,0,index[0],k);

}

else{

return findK(arr,index[1]+1,end,k);

}

}

//使用bfprt算法寻找中位数

public int selectKey(int[] arr,int start,int end){

if(end-start<=4){

return midKey(arr,start,end);

}

int[] temp=new int[(end-start)/5+1];

int j=0;

for(int i=start;i<=end;i+=5){

temp[j++]=midKey(arr,i,Math.min(end,i+4));

}

return selectKey(temp,0,(end-start)/5);

}

//按中位数值快速排序

public int[] quickSort(int[] arr,int start,int end,int key){

int[] index=new int[2];

if(start==end){

index[0]=index[1]=start;

return index;

}

int cur=start;

int left=start;

int right=end;

while(cur<=right){

if(arr[cur]>key){

swap(arr,cur,right--);

}

else if(arr[cur]<key){

swap(arr,cur++,left++);

}

else{

cur++;

}

}

index[0]=left;

index[1]=right;

return index;

}

//对没五个的小组进行插入排序并返回小组中位数。

public int midKey(int[] arr,int start,int end){

if(start==end){

return arr[start];

}

int mid=(start+end)/2;

for(int i=start+1;i<=end;i++){

int key=arr[i];

int j=i-1;

while(j>=start&&key<arr[j]){

arr[j+1]=arr[j--];

}

arr[++j]=key;

}

return arr[mid];

}

public void swap(int[] arr,int i,int j){

int temp;

temp=arr[i];

arr[i]=arr[j];

arr[j]=temp;

}

无序数组中最小的k个数

对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的k个数,顺序与原数组中元素顺序一致。

给定一个整数数组A及它的大小n,同时给定k,请返回其中最小的k个数。

测试样例:
[1,2,4,3],4,2

返回:[1,2]


(1)堆实现:

(2)bfprt

public int[] findKthNumbers(int[] A, int n, int k) {

if(A==null||n<=k||k<1){

return A;

}

int[] result=new int[k];

int key;

int j=0;

int[] copyArr=new int
;

for (int i = 0; i < n; i++) {

copyArr[i] = A[i];

}

key=findK(copyArr,0,n-1,k);//找到第k小数的值;

int count=0;

for(int i=0;i<n;i++){

if(A[i]<key){

count++;

}

}

int c=k-count;

for(int i=0;i<n;i++){

if(A[i]<key){

result[j++]=A[i];

}

if(A[i]==key&&c-->0){

result[j++]=A[i];

}

}

return result;

}

public int findK(int[] arr,int start,int end,int k){

int key;

int[] index=new int[2];

key=selectKey(arr,start,end);//找中位数。

index=quickSort(arr,start,end,key);//以中位数为基准,快速排序。

if(index[0]<=k-1&&k-1<=index[1]){

return arr[index[0]];

}

else if(index[0]>k-1){

return findK(arr,0,index[0],k);

}

else{

return findK(arr,index[1]+1,end,k);

}

}

//使用bfprt算法寻找中位数

public int selectKey(int[] arr,int start,int end){

if(end-start<=4){

return midKey(arr,start,end);

}

int[] temp=new int[(end-start)/5+1];

int j=0;

for(int i=start;i<=end;i+=5){

temp[j++]=midKey(arr,i,Math.min(end,i+4));

}

return selectKey(temp,0,(end-start)/5);

}

//按中位数值快速排序

public int[] quickSort(int[] arr,int start,int end,int key){

int[] index=new int[2];

if(start==end){

index[0]=index[1]=start;

return index;

}

int cur=start;

int left=start;

int right=end;

while(cur<=right){

if(arr[cur]>key){

swap(arr,cur,right--);

}

else if(arr[cur]<key){

swap(arr,cur++,left++);

}

else{

cur++;

}

}

index[0]=left;

index[1]=right;

return index;

}

//对没五个的小组进行插入排序并返回小组中位数。

public int midKey(int[] arr,int start,int end){

if(start==end){

return arr[start];

}

int mid=(start+end)/2;

for(int i=start+1;i<=end;i++){

int key=arr[i];

int j=i-1;

while(j>=start&&key<arr[j]){

arr[j+1]=arr[j--];

}

arr[++j]=key;

}

return arr[mid];

}

public void swap(int[] arr,int i,int j){

int temp;

temp=arr[i];

arr[i]=arr[j];

arr[j]=temp;

}





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