java实现根号n路归并排序

最近算法课给了一道题:

这里写图片描述


思路:

对比二路归并算法,这个题的难点在于,根号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

结语

没有优化,而且没有仔细去检查,有问题可以评论中指出,谢谢

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值