Bubblesort is probably one of the really bad examples to try recursion.
My suggested recursion pattern for bubblesort would be:
function bubblesort (input: some integer array):
if input is empty:
return input
else:
do one bubble sort run for input
subarray = bubblesort(unsorted part of input)
return subarray append sorted part of input
In this way, we will sort the whole array piecewise for each call.
Why does it work? Because every bubble sort run, we will put at least the largest element to the rightmost index.
We know that all elements until the last swap are in unknown state, all after the last swap are sorted.
In Java code:
/** Sorts the given array with a recursive bubblesort. Modifies the given array */
public static int[] bubbleSort(final int[] array) {
if (array.length == 0)
return array;
int lastSwapIndex = 0;
for (int i = 1; i < array.length; i++) {
if (array[i - 1] > array[i]) {
final int temp = array[i - 1];
array[i - 1] = array[i];
array[i] = temp;
lastSwapIndex = i;
}
}
System.arraycopy(bubbleSort(Arrays.copyOfRange(array, 0, lastSwapIndex)), 0, array, 0, lastSwapIndex);
return array;
}
(To create a non-modifying version should be quite easy for every reader, just create a copy before modifying it)
Nevertheless, I would suggest to use a list. It would look like this:
/** Sorts the given list with a recursive bubblesort. Modifies the given list */
public static List<Integer> bubbleSort(final List<Integer> list) {
if (list.isEmpty())
return list;
int lastSwapIndex = 0;
for (int i = 1; i < list.size(); i++) {
if (list.get(i - 1) > list.get(i)) { //slow if no random access list
final int temp = list.get(i - 1);
list.set(i - 1, list.get(i));
list.set(i, temp);
lastSwapIndex = i;
}
}
bubbleSort(list.subList(0, lastSwapIndex));
return list;
}
Or if we do not want to modifiy the given list:
/** Sorts the given list with a recursive bubblesort. */
public static List<Integer> bubbleSort(final List<Integer> list) {
if (list.isEmpty())
return list;
int lastSwapIndex = 0;
for (int i = 1; i < list.size(); i++) {
if (list.get(i - 1) > list.get(i)) { //slow if no random access list
final int temp = list.get(i - 1);
list.set(i - 1, list.get(i));
list.set(i, temp);
lastSwapIndex = i;
}
}
final List<Integer> result = bubbleSort(new ArrayList<>(list.subList(0, lastSwapIndex)));
result.addAll(list.subList(lastSwapIndex, list.size()));
return result;
}