繁体   English   中英

Java 快速排序算法 indexoutofbounds

[英]Java quickSort algorithm indexoutofbounds

在了解它之后,我正在尝试实现一个快速排序算法。

package qsort;

public class QuickSort {
    
    public static void main(String[] args) {
        int arr[] = {10,16,8,12,15,6,3,9,5,100};
        quickSort(arr,0,(arr.length-1));
        for(int number:arr) {
            System.out.println(number);
        }
    }

    
    public static void quickSort(int[] arr, int l, int h) {
        if(l<h) {
            
            int j=partition(arr,l,h); //pivot position as j retrieved as the one sorted element
            int[] left = new int[j];
            int[] right = new int[(arr.length-j)];
            for(int index=0;index<j;index++) {
                left[index]=arr[index];
                }
            for(int index=j;index<arr.length;index++) {
                right[index-(j)]=arr[index];
            }
            
            quickSort(left,0,j);             //Sorts the first half of the array (i.e the elements before pivot
            quickSort(right,j+1,arr.length-1);            //SOrts the second half after pivot
        }
    }
    
    public static int partition(int[] arr, int l, int h) {
        
        if(arr[l]>arr[h]) {
            swap(arr[l],arr[h]);
        }
        
        
        int pivot = arr[l];
        int i=l;
        int j=h;     //i starts from the first and increments;  j starts from last and decrements
        while(i<j) {
            
            do {
                i++;
            }while(arr[i]<=pivot);          //i keeps incrementing until i points to a value greater than pivot
        
            do {
                j--;
            }while(arr[j]>pivot);               //j keeps decrementing until it finds a value less than pivot
        
            if(i<j) {
                swap(arr[i],arr[j]);
            }
        }
        swap(arr[l],arr[j]);            // swapping the first element l with the element in j so that the pivotal element can be ordered
        return j;                      //finally j points to the one sorted index where pivot should be placed
        
    }
    
    public static void swap(int a, int b){
        int temp=a;
        a=b;
        b=temp;
    }
}

而且我对 IndexOutOfBoundsException 一无所知,我无法找出它发生的位置或方式。 任何帮助将非常感激。

有这些问题:

  • swap不交换。 它只是交换两个局部变量的值,但对数组一无所知。 swap退出时,这两个局部变量被丢弃并且没有真正改变。 您需要将数组引用传递给swap和所涉及的两个索引,然后swap应该在这两个给定索引处更改该数组中的值。

  • left获取j值,但随后进行递归调用, h等于j ,这是一个超出范围的索引。 left的数组有j个元素,所以它的最后一个索引是j-1 ,而不是j

  • right获取剩余的值,但随后使用l等于j+1进行递归调用,但这与right无关,其相关值从索引 0 开始,而不是从索引j+1开始。

  • 将值复制到新的 arrays left right整个想法是错误的。 这不是快速排序应该如何工作的。 即使leftright可以成功排序,这对arr没有任何影响,它仍然未排序。 所以你会白白干活。 Quicksort 是一种就地排序算法,因此您应该始终使用arr ,而不是使用它的分区副本。

以下是相关功能的更正:

    public static void quickSort(int[] arr, int l, int h) {
        if(l<h) {
            int j=partition(arr,l,h);
            // Don't create new arrays here, but sort the partition in-place:
            quickSort(arr,l,j-1);
            quickSort(arr,j+1,h);
        }
    }

    public static int partition(int[] arr, int l, int h) {
        if (arr[l]>arr[h]) {
            swap(arr, l, h); // swap needs the array reference, and two indices
        }
        int pivot = arr[l];
        int i=l;
        int j=h;
        while(i<j) {
            do {
                i++;
            }while(arr[i]<=pivot);
            do {
                j--;
            }while(arr[j]>pivot);
            if(i<j) {
                swap(arr, i, j); // see above
            }
        }
        swap(arr, l, j); // see above
        return j;
    }
    
    // swap needs the array reference and the indices to perform the swap in the array
    public static void swap(int[] arr, int i, int j){
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }

我对 IndexOutOfBoundsException 一无所知,我无法找出它发生的位置或方式。

调试意味着您阅读了包含此错误消息的堆栈跟踪。 它会给你它出现的行号(它在partition的第一行)。 然后,当您确定该行时,您可以开始真正使用调试器,设置断点并检查变量。 您会注意到的第一件事是arr永远不会改变:其中没有任何东西被移动。 因此,您将继续调试和解决一件又一件的事情。 这就是我对你的代码所做的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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