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

java实现根号n路归并排序

2016-11-17 13:43 441 查看

最近算法课给了一道题:



思路:

对比二路归并算法,这个题的难点在于,根号n每次的子问题个数不定,是上个问题的根号n。但是还是能从二路归并中找到相似的思路。

代码:

package chapter1;

import java.util.Arrays;

public class MergeSort {
static int count = 0;

private static final int MAX_LENGTH = 211;
private static int [] copy = new int[MAX_LENGTH];

private static void createData(int [] a){
for(int i  = 0;i< a.length ; i++){
a[i] = (int) (Math.random()*1000);
}

for (int i : a) {
System.out.print(i+" ");
}

System.out.println("\n------------------------------------before sort--------------------------");
}

private static void swap(int [] array,int left,int right){
int temp = array[left];
array[left] = array[right];
array[right] = temp;

}

/**
* 基础排序
* @param array 数组
* */
private static void sort(int [] array,int left,int right){
if(array.length == 2){
if(array[left] > array[right])
swap(array,left,right);
}else{
if(array[left] > array[left+1])
swap(array,left,left+1);
if(array[left] > array[right])
swap(array,left,right);
if(array[left+1] > array[right])
swap(array,left+1,right);
}

System.out.println("in sort:");
for(int i = left; i <= right;i++)
System.out.print(array[i]+" ");

System.out.println();

}

/**
* 算法实现(递归)
* @param Array 待排序的数组
*
* */
private static void mergeSort(int [] array,int left,int right){
if(right == left)
return ;

int len = right - left + 1;
if(len == 2 || len ==3){
sort(array,left,right);
return ;
}

final int SQRT = (int) Math.sqrt(len);//根号n
final int SIZE = (int) (len)/SQRT;//每一个打大小

for(int i=0 ; i < SQRT ;i++ ){
if(i != SQRT - 1)
mergeSort(array, left+i*SIZE, left+i*SIZE+SIZE-1);
else
mergeSort(array, left+i*SIZE,right);//array.length - 1
}

for (int s : array)
System.out.print(s+" ");
System.out.println("\n---------------"+count+++"----------------------");
merge(array, left, right);
}

/**
* 将根号n个数组合并起来,加入一个辅助数组
*
* */
private static void merge(int [] array,int left , int right){
int len = right - left +1;

final int SQRT = (int) Math.sqrt(len);//根号n
final int SIZE = (int) (len)/SQRT;//每一个打大小

int [] [] a = new int[SQRT][];
for(int i=0 ; i < SQRT ;i++ ){
if(i != SQRT - 1)
a[i] = Arrays.copyOfRange(array, left+i*SIZE, left+i*SIZE+SIZE);
else
a[i] = Arrays.copyOfRange(array, left+i*SIZE, right+1);
}

int [] index = new int[SQRT];
for(int j = left;j <= right ;j++){
int min = Integer.MAX_VALUE;
int flag = 0;
for(int i=0 ; i < SQRT ;i++ ){
if(index[i] == a[i].length)
continue;
if(a[i][index[i]] < min){
min = a[i][index[i]];
flag = i;
}
}
index[flag]++;
copy[j] = min;
}

for(int k = left ; k <= right ; k++)
array[k] = copy[k];
}

public static void main(String[] args) {

int[] array = new int[MAX_LENGTH];
createData(array);

mergeSort(array,0,array.length-1);

System.out.println("----------------------after--------------------------");
for (int i : array) {
System.out.print(" "+i);
}

}

}


输出:

ps:(这里我将
MAX_LENGTH
改为了17方便显示)

395 449 313 307 486 796 239 820 164 208 860 901 300 728 930 32 881

————————————before sort————————–

in sort:

395 449

in sort:

307 313

395 449 307 313 486 796 239 820 164 208 860 901 300 728 930 32 881

—————0———————-

in sort:

486 796

in sort:

239 820

307 313 395 449 486 796 239 820 164 208 860 901 300 728 930 32 881

—————1———————-

in sort:

164 208

in sort:

860 901

307 313 395 449 239 486 796 820 164 208 860 901 300 728 930 32 881

—————2———————-

in sort:

300 728

in sort:

32 881 930

307 313 395 449 239 486 796 820 164 208 860 901 300 728 32 881 930

—————3———————-

307 313 395 449 239 486 796 820 164 208 860 901 32 300 728 881 930

—————4———————-

———————-after————————–

32 164 208 239 300 307 313 395 449 486 728 796 820 860 881 901 930

结语

没有优化,而且没有仔细去检查,有问题可以评论中指出,谢谢
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐