Java自上而下的合并排序-Stackoverflow错误

时间:2020-07-26 19:36:21

标签: java

我正在尝试使用pseudocode from Wikipedia在Java中实现自上而下的合并排序算法。

我的问题是我的代码有时会引发StackOverflowError,但并非总是如此。我已经检查过我的代码多次与伪代码匹配,并且找不到错误所在。

这是我的Java代码:

import java.util.ArrayList;
import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Random r = new Random();
        ArrayList<Integer> numbers = new ArrayList<Integer>();
        for (int i = 1; i <= 15; i++) {
            numbers.add(r.nextInt(100));
        }
        numbers = mergeSort(numbers);
        System.out.println(numbers);
    }

    public static ArrayList<Integer> mergeSort(ArrayList<Integer> m) {
        if (m.size() <= 1) {
            return m;
        }
        ArrayList<Integer> left = new ArrayList<Integer>();
        ArrayList<Integer> right = new ArrayList<Integer>();
        for (Integer x : m) {
            if (m.indexOf(x) < (m.size()) / 2)
                left.add(x);
            else {
                right.add(x);
            }
        }
        left = mergeSort(left);
        right = mergeSort(right);
        return merge(left, right);
    }

    private static ArrayList<Integer> merge(ArrayList<Integer> l, ArrayList<Integer> r) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        while (l.size() > 0 && r.size() > 0) {
            if (l.get(0) <= r.get(0)) {
                result.add(l.get(0));
                l.remove(0);
            }
            else {
                result.add(r.get(0));
                r.remove(0);
            }
        }
        while (l.size() > 0) {
            result.add(l.get(0));
            l.remove(0);
        }
        while (r.size() > 0) {
            result.add(r.get(0));
            r.remove(0);
        }
        return result;
    }
}

2 个答案:

答案 0 :(得分:2)

当元素重复时,您的算法会遇到问题,因为indexOf仅返回第一个元素的索引。请改用基于索引的for循环。 Demo

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

答案 1 :(得分:0)

在mergeSort方法中,需要稍微更改for循环,然后重试。

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