ive rewritten it a hundred times, i keep getting an IndexOutOfBound exception. It may be an issue if the first for loop that fills in the left array, but im not sure how to change the logic.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10 at mergeSortWithTwist.merge(mergeSortWithTwist.java:57)
i don't know what else to do, any help is appreciated !
public static void merge(int[] inputArr, int p, int q, int r) {
int n1 = q-p+1;
int n2 = r-q;
int[] leftHalf = new int[n1];
int[] rightHalf = new int[n2];
for(int i = 0; i < n1; i++)
leftHalf[i] = inputArr[p+i-1];
for(int i = 0; i < n2; i++)
rightHalf[i] = inputArr[q+i];
leftHalf[n1+1] = Integer.MAX_VALUE;
rightHalf[n2+1] = Integer.MAX_VALUE;
int i = 0;
int j = 0;
for(int k = 0; k < r; k++) {
if(leftHalf[i] <= rightHalf[j]){
inputArr[k] = leftHalf[i];
i++;
}
else {
inputArr[k] = rightHalf[j];
j++;
}
}
}
public static void merge_sort(int[] inputArr, int p, int r) {
if(p<r) {
int q = (p + r) / 2;
merge_sort(inputArr,p,q);
merge_sort(inputArr,q+1,r);
merge(inputArr,p,q,r);
}
}
There are several issues:
leftHalf[n1+1] =assigns to an out of range index.leftHalfhasn1entries, son1+1and evenn1are out of range.The values
n1andn2are determined by the size of the left and right partitions, which is fine, but as you want an extra entry for storingInteger.MAX_VALUE, you would need to allocate one more entry when definingleftHalfandrightHalf.The assignment
leftHalf[i] = inputArr[p+i-1];will evaluateinputArr[p-1]wheniis zero, but that is an index that is outside the left partition, and could even be -1 (whenpis 0), which is what your exception is complaining about. This should beinputArr[p+i]. Similarly, the next statement should assign an index that is one greater.The final "merge" loop starts with a wrong value for
k. Thiskshould not start at 0, but atp. Secondly, it should not stop before reachingr, but includeras well.Here is your
mergefunction with corrections for the above issues:Note that all these bugs can be found by meticulous debugging: stepping through the code, setting breakpoints, inspecting variables, possibly printing them.
Using
MAX_VALUE?As noted in comments: although the use of
MAX_VALUEas "stopper" value simplifies the merge part of your code a bit, this requires that the input will not have this value as actual data value. IfMAX_VALUEis considered a valid data value (and why not?), you cannot really use this shortcut, and would better do it without: