合并排序实现java

时间:2014-02-21 14:37:00

标签: java sorting mergesort

我正在尝试实现自己的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;
    }       
}

3 个答案:

答案 0 :(得分:2)

您的代码存在一些问题。你的方法是正确的

  1. 在join方法中,由于while循环正在使用

    ,因此您将在列表中保留一些元素

    lp&lt; left.size()&amp;&amp; rp&lt; right.size()

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

    while(lp < left.size()) {
        fin.add(left.get(lp++));
    }
    while(rp < right.size()) {
    
        fin.add(right.get(rp++));
    }
    
  2. 你的msort方法有问题,你没有使用msort的返回值,所以你需要这个:

    left = msort(左);

    right = msort(右);

  3. 希望这有帮助。

答案 1 :(得分:1)

您将在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);
}

msort方法中调用main时类似:

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所示。

答案 2 :(得分:0)

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

不会更改l,而是返回已排序的列表。所以你应该做

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