I am trying to implement the top-down merge sort algorithm in Java, using the pseudocode from Wikipedia.
My problem is that my code sometimes throws a StackOverflowError, but not always. I have checked that my code matches the pseudocode several times and cannot find what is wrong with it.
Here is my Java code:
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; } }
Advertisement
Answer
Your algorithm encounters issues when there are duplicate elements, as indexOf
will only return the index of the first one. Use a index-based for
loop instead. 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)); } }