简体   繁体   中英

Priority in mergeSort algorithm function

I have met a problem with mergeSort function. When I change the following line:

if( j>end || (arr[i]<=arr[j] && i<=mid )){//HERE is the problem.

to

if(( arr[i]<=arr[j] && i<=mid) || j>end ){//Only change the sequence of conditional expressions.

the result is totally different. The first one's output is 2 4 3 1 1 2 3 4 . The changed one's output is 2 4 3 1 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4 at test.mergeSort(test.java:26) at test.mergeSort(test.java:24) at test.main(test.java:9) What is the problem with this change? Thanks: The Full code is below:

public class test{
    public static void main(String[] args) {
        int[]arr={2,4,3,1};
        int[]temp=new int[arr.length];
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }
        mergeSort(arr,temp,0,arr.length-1);
        for(int i=0;i<arr.length;i++){
            System.out.println(arr[i]);
        }
    }
    public static void mergeSort(int[]arr,int[]temp,int start,int end){
        //only sort when start<end
        if(start<end){
            int mid=(start+end)>>1;
            //3 pointers to left array, right array, and temporary array
            int i=start;
            int j=mid+1;
            int k=0;
            
            mergeSort(arr,temp,start,mid);
            mergeSort(arr,temp,mid+1,end);

            while(i<=mid||j<=end){
                if( j>end || (arr[i]<=arr[j] && i<=mid )){//HERE is the problem.
                    temp[k++]=arr[i++];
                }else{
                    temp[k++]=arr[j++];
                }
            }
            System.arraycopy(temp,0,arr,start,k);
        }
    }

Only change the sequence of conditional expressions.

Refer to Equality, Relational, and Conditional Operators which is part of Oracle's Java tutorials.
Here is a quote:

These operators exhibit "short-circuiting" behavior, which means that the second operand is evaluated only if needed.

In other words, in your first condition, ie

j>end || (arr[i]<=arr[j] && i<=mid )

If j is greater than end , the rest of the condition will not be evaluated . Similarly, in the second condition, ie

( arr[i]<=arr[j] && i<=mid) || j>end

If the part before the [logical] or operator ( || ) is true then j will not be checked.

So changing the sequence of conditional expressions can make a big difference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM