[英]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
整个想法是错误的。 这不是快速排序应该如何工作的。 即使left
和right
可以成功排序,这对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.