[英]Java quickSort algorithm indexoutofbounds
I'm trying to implement a quickSort algorithm after learning about it.在了解它之后,我正在尝试实现一个快速排序算法。
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;
}
}
And I've been clueless about IndexOutOfBoundsException and I'm not able to find out where or how it occurs.而且我对 IndexOutOfBoundsException 一无所知,我无法找出它发生的位置或方式。 Any help would be much appreciated.
任何帮助将非常感激。
There are these issues:有这些问题:
swap
doesn't swap. swap
不交换。 It just swaps the values of two local variables, but has no knowledge about an array.它只是交换两个局部变量的值,但对数组一无所知。 When
swap
exits, those two local variables are discarded and nothing really changed.当
swap
退出时,这两个局部变量被丢弃并且没有真正改变。 You need to pass the array reference to swap
and the two indices that are involved, and then swap
should change the values in that array at those two given indices.您需要将数组引用传递给
swap
和所涉及的两个索引,然后swap
应该在这两个给定索引处更改该数组中的值。
left
gets j
values, but then a recursive call is made with h
equal to j
, which is an index that is out of range. left
获取j
值,但随后进行递归调用, h
等于j
,这是一个超出范围的索引。 The left
array has j
elements, so its last index is j-1
, not j
. left
的数组有j
个元素,所以它的最后一个索引是j-1
,而不是j
。
right
gets the remaining values, but then the recursive call is made with l
equal to j+1
, but that has no relation to right
, whose relevant values start at index 0, not at index j+1
. right
获取剩余的值,但随后使用l
等于j+1
进行递归调用,但这与right
无关,其相关值从索引 0 开始,而不是从索引j+1
开始。
The whole idea to copy values into new arrays left
and right
is wrong.将值复制到新的 arrays
left
right
整个想法是错误的。 This is not how quicksort is supposed to work.这不是快速排序应该如何工作的。 Even if
left
and right
would be successfully sorted, this does not have any impact on arr
, which remains unsorted.即使
left
和right
可以成功排序,这对arr
没有任何影响,它仍然未排序。 So you'd have done work for nothing.所以你会白白干活。 Quicksort is an inplace sorting algorithm, so you should always be working with
arr
, not with copies of partitions of it. Quicksort 是一种就地排序算法,因此您应该始终使用
arr
,而不是使用它的分区副本。
Here is the correction of the relevant functions:以下是相关功能的更正:
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;
}
I've been clueless about IndexOutOfBoundsException and I'm not able to find out where or how it occurs.
我对 IndexOutOfBoundsException 一无所知,我无法找出它发生的位置或方式。
Debugging means you read the stack trace that includes this error message.调试意味着您阅读了包含此错误消息的堆栈跟踪。 It will give you the line number where it occurs (it was on the first line in
partition
).它会给你它出现的行号(它在
partition
的第一行)。 Then when you have identified that line, you can start to really use a debugger, setting breakpoints and inspecting variables.然后,当您确定该行时,您可以开始真正使用调试器,设置断点并检查变量。 One of the first things you would notice, is that
arr
never changes: nothing gets moved in it.您会注意到的第一件事是
arr
永远不会改变:其中没有任何东西被移动。 And so you would continue to debug and resolve one thing after the other.因此,您将继续调试和解决一件又一件的事情。 It is what I did with your code.
这就是我对你的代码所做的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.