我正在尝试实现自己的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;
}
}
答案 0 :(得分:2)
您的代码存在一些问题。你的方法是正确的
在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++));
}
你的msort方法有问题,你没有使用msort的返回值,所以你需要这个:
left = msort(左);
right = msort(右);
希望这有帮助。
答案 1 :(得分:1)
您将在msort
方法中返回已排序的列表,但从未在代码中的任何位置分配此值。可能的解决方案可能是在对left
和right
进行排序后重新分配:
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); 然后尝试打印该排序列表。