我正在遵循以下伪代码:
function quicksort(array)
if length(array) > 1
pivot := select any element of array
left := first index of array
right := last index of array
while left ≤ right
while array[left] < pivot
left := left + 1
while array[right] > pivot
right := right - 1
if left ≤ right
swap array[left] with array[right]
left := left + 1
right := right - 1
quicksort(array from first index to right)
quicksort(array from left to last index)
但是当我尝试在Java中实现它时,我会插入代码:
import java.util.Arrays;
public class ALGQuickSort {
public static void main(String[] args) {
int[] array = {6, 3, 4, 8, 9, 10, 1};
quickSort(array);
System.out.println(Arrays.toString(array));
}
public static void quickSort(int[] array) {
int pivot = array[array.length - 1];
if (array.length > 1) {
int left = 0;
int right = array.length - 1;
while (left <= right) {
while (array[left] < pivot) {
left++;
}
while (array[right] > pivot) {
right--;
}
if (left <= right) {
swap(array[left], array[right]);
right--;
left++;
}
int[] array1 = Arrays.copyOfRange(array, 0, right);
int[] array2 = Arrays.copyOfRange(array, left, array.length - 1);
quickSort(array1);
quickSort(array2);
}
}
}
public static void swap(int a, int b) {
int aux = a;
a = b;
b = aux;
}
}
系统在屏幕上显示以下错误:
线程“ main”中的异常java.lang.IllegalArgumentException:5> 4 在java.util.Arrays.copyOfRange(Arrays.java:3591)在 alg.quicksort.ALGQuickSort.quickSort(ALGQuickSort.java:43)在 alg.quicksort.ALGQuickSort.quickSort(ALGQuickSort.java:44)在 alg.quicksort.ALGQuickSort.main(ALGQuickSort.java:21) C:\ Users \ Alex \ AppData \ Local \ NetBeans \ Cache \ 8.2 \ executor-snippets \ run.xml:53: Java返回:1
该错误在该行中:
int[] array2 = Arrays.copyOfRange(array, left, array.length - 1);
有人可以帮助我吗?
答案 0 :(得分:1)
首先,两行
int[] array1 = Arrays.copyOfRange(array, 0, right);
int[] array2 = Arrays.copyOfRange(array, left, array.length - 1);
是错误的。 您不得复制阵列。由于在递归调用中对临时副本进行排序,这将阻止Quicksort算法起作用。排序后的子数组将被丢弃。
程序中的另一个错误引发了一个例外:Arrays.copyOfRange
的第三个参数是独占的。即它不会将元素from
复制到to
而是将from
复制到to - 1
。但是您已经从上限减去了一个,在Quicksort中可能会出现其中一个子数组的尺寸为 0 。在这种情况下,要复制的范围变为负数。例外。
还有第三个错误:您交换了伪代码的前两行。这将在空数组上崩溃。
最后,您不能以这种方式实现Quicksort算法,如伪代码所示,因为Java (与C不同)不支持数组切片。
您需要以将算法分为两种方法的方式来修改算法:
一种对数组切片进行递归排序的方法:
请注意,我用from
和to
替换了数组的开始和结束。
public static void quickSort(int[] array, int from, int to) {
if (array.length <= 1)
return;
int pivot = array[to];
int left = from;
int right = to;
while (left <= right) {
while (array[left] < pivot)
left++;
while (array[right] > pivot)
right--;
if (left <= right) {
swap(array[left], array[right]);
right--;
left++;
}
quickSort(array, from, right);
quickSort(array, left, to);
}
}
还有第二种方法对整个数组进行排序,该方法针对整个数组调用上述方法。
public static void quickSort(int[] array) {
return quickSort(array, 0, array.length - 1);
}
答案 1 :(得分:1)
对快速排序算法的改进/更正:
right+1 == left
(想一想,您就会明白为什么这是真的)。现在将数组[left]与pivot元素交换,并递归调用2个不同的子数组(pivot的左子数组为beginIndex..right
,pivot的右子数组为left+1..endIndex
,其中我认为您需要对array[beginIndex..endIndex]
)进行排序startIndex
和endIndex
来表示想要的子数组排序)如果您打算将索引为index1和index2的数组元素互换,那么以下代码将起作用:
public static void swap(int[] array, int index1, int index2) {
int aux = array[index1];
array[index1] = array[index2];
array[index2] = aux;
}
以下是具有上述所有建议更改的最终代码:
public static void main(String[] args) {
int[] array = {6, 30, 7, 23, 4, 8, 9, 10, 1, 90};
quickSort(array, 0, array.length - 1);
System.out.println(Arrays.toString(array));
}
public static void quickSort(int[] array, int beginIndex, int endIndex) {
// System.out.println("called quick sort on the following : " + beginIndex + " " + endIndex);
int arrayLength = endIndex - beginIndex + 1;
int pivot = array[endIndex];
if (arrayLength > 1) {
int left = beginIndex;
int right = endIndex - 1;
while (left <= right) {
// System.out.println(left + " " + right);
while (left <= endIndex && array[left] < pivot) {
left++;
}
while (right >= beginIndex && array[right] > pivot) {
right--;
}
if (left <= right) {
swap(array, left, right);
right--;
left++;
}
}
swap(array, left, endIndex); // this is crucial, and you missed it
if (beginIndex < right) {
quickSort(array, beginIndex, right);
}
if (left + 1 < endIndex) {
quickSort(array, left + 1, endIndex);
}
}
}
private static void swap(int[] array, int index1, int index2) {
int aux = array[index1];
array[index1] = array[index2];
array[index2] = aux;
}