【问题标题】:Merge Sort Implementation java合并排序实现java
【发布时间】:2014-02-21 14:37:00
【问题描述】:

我正在尝试实现我自己的 Mergesort 功能,但很难弄清楚什么不起作用。

UnSorted:[6, 1, 2, 7, 2, 3, 9, 7, 6] 的输出是Sorted:[2, 3, 6, 1, 2, 7]

这是我目前所拥有的:

public class mergeSort {

    public static void main(String[] args) {
        List<Integer> l = new ArrayList<Integer>();
        Random rd = new Random();

        for (int i = 1; i < 10; i++) {
            l.add(rd.nextInt(10) + 1);
        }   

        System.out.println("UnSorted: " + l);
        msort(l);
        System.out.println("Sorted: "+msort(l));
    }

    public static List<Integer> msort(List<Integer> l) {     
        if (l.size() <= 1) {
            return l;
        }

        List<Integer> left = new ArrayList<Integer>();
        List<Integer> right = new ArrayList<Integer>();

        for (int i = 0; i < (l.size() / 2); i++) {
            left.add(l.get(i));
        }
        for (int i = l.size() / 2; i < l.size(); i++) {
            right.add(l.get(i));
        }

        msort(left);
        msort(right);
        //System.out.println(left + "" +right);

        return join(left,right);
    }

    public static List<Integer> join(List<Integer> left, List<Integer> right) { 
        /*if (right.size() == 0) {
            return left;
        }
        if (left.size() == 0) {
            return right;
        }*/

        List<Integer> fin = new ArrayList<Integer>();
        // pointers
        int lp = 0, rp = 0, fp = 0;

        while (lp < left.size() && rp < right.size()) { 
            if (left.get(lp) < right.get(rp)) {
                fin.add(left.get(lp));  
                lp++;
            } else {
                fin.add(right.get(rp));  
                rp++;        
            }
            fp++;
        }   
        return fin;
    }       
}

【问题讨论】:

    标签: java sorting mergesort


    【解决方案1】:

    您的代码存在几个问题。不过你的方法是对的

    1. 在 join 方法中,由于您的 while 循环正在使用,您将一些元素留在列表中

      lp

      它将循环直到其中一个列表被添加到 fin 并且可能仍然有一些元素留在其他列表中。所以你需要另外两个循环来适应这个:

      while(lp < left.size()) {
          fin.add(left.get(lp++));
      }
      while(rp < right.size()) {
      
          fin.add(right.get(rp++));
      }
      

    2. 你的 msort 方法也有问题,你没有使用 msort 的返回值,所以你需要这个:

      left = msort(left);

      right = msort(right);

    希望这会有所帮助。

    【讨论】:

    • 我认为这是fp的目的,但它没有在逻辑中的任何地方实现(fp在每个循环中递增,但从未测试过)
    • 欢迎您@rohstar .. 玩得开心编码:)
    【解决方案2】:

    您在msort 方法中返回排序列表,但从未在代码中的任何位置分配此值。一个可能的解决方案可能是在对 leftright 进行排序后重新分配它们:

    public static List<Integer> msort(List<Integer> l){
        if (l.size() <= 1) {
            return l;
        }
        List<Integer> left = new ArrayList<Integer>();
        List<Integer> right = new ArrayList<Integer>();
        for(int i = 0; i <(l.size()/2);i++){
            left.add(l.get(i));
        }
        for(int i = l.size()/2; i <l.size();i++){
            right.add(l.get(i));
        }
        //this is where you should assign them
        left = msort(left);
        right = msort(right);
        //System.out.println(left + "" +right);
        return join(left,right);
    }
    

    main 方法中调用msort 时类似:

    l = msort(l);
    

    正如@Sanjeev 所指出的,您还缺少join 方法中的数组元素。使用那段代码来修复它(取自his/her answer):

    while (lp < left.size() && rp < right.size()) {
        //logic inside this while loop...
    }
    //add this code
    while(lp < left.size()) {
        fin.add(left.get(lp++));
    }
    while(rp < right.size()) {
        fin.add(right.get(rp++));
    }
    return fin;
    

    除此之外,您应该避免使用List#get 方法,因为取决于类实现可能需要 O(n) 时间,例如LinkedList,改为使用Iterator,如图here

    【讨论】:

    • 感谢您的回复!
    【解决方案3】:

    一个明显的问题是您的合并方法返回一个排序列表。它不会修改自己的输入列表。这本身不是问题,但这意味着您的电话: msort(l);

    不会改变 l,而是返回一个排序列表。所以你应该这样做

    列表 sortedList=msort(l); 然后尝试打印该排序列表。

    【讨论】:

    • 不确定这是否能解决问题,但绝对是朝着正确方向迈出的一步
    猜你喜欢
    • 2015-09-10
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多