美好的一天!我这里有一个Java程序来执行快速排序。它读取一个文件,然后对其中的前10,000个单词进行排序。我在他的算法导论,第二版中遵循了Thomas Cormen的伪代码。
import java.io.*;
import java.util.*;
public class SortingAnalysis {
public static int partition(String[] A, int p, int r) {
String x = A[r];
int i = p-1;
for (int j=p; j < r-1; j++) {
int comparison = A[j].compareTo(x);
if (comparison<=0) {
i=i+1;
A[i] = A[j];
}
}
A[i+1] = A[r];
return i+1;
}
public static void quickSort(String[] a, int p, int r) {
if (p < r) {
int q = partition(a, p, r);
quickSort(a, p, q-1);
quickSort(a, q+1, r);
}
}
public static void main(String[] args) {
final int NO_OF_WORDS = 10000;
try {
Scanner file = new Scanner(new File(args[0]));
String[] words = new String[NO_OF_WORDS];
int i = 0;
while(file.hasNext() && i < NO_OF_WORDS) {
words[i] = file.next();
i++;
}
long start = System.currentTimeMillis();
quickSort(words, 0, words.length-1);
long end = System.currentTimeMillis();
System.out.println("Sorted Words: ");
for(int j = 0; j < words.length; j++) {
System.out.println(words[j]);
}
System.out.print("Running time: " + (end - start) + "ms");
}
catch(SecurityException securityException) {
System.err.println("Error");
System.exit(1);
}
catch(FileNotFoundException fileNotFoundException) {
System.err.println("Error");
System.exit(1);
}
}
}
然而,当我运行代码时,控制台说
Exception in thread "main" java.lang.StackOverflowError
at SortingAnalysis.partition and quickSort
我认为错误只是因为大尺寸(即10000),所以我把它减少到100。但是,它仍然不会对文件中的前100个单词进行排序,而是显示100次单词的第100个单词。
请帮我修复代码。我是Java的新手,我需要你们的帮助。非常感谢你!
编辑:我现在编辑了我的代码。即使 NO_OF_WORDS
达到10000,它也不会出现错误。问题是它会停止错误的序列。
答案 0 :(得分:2)
你有两个问题:
partition()
中的循环应该运行到j <= r - 1
,您会提前跳出来。
您不是在交换元素。请尝试以下代码:
public static int partition(String[] A, int p, int r) {
String x = A[r];
int i = p - 1;
for (int j = p; j <= r - 1; j++) {
int comparison = A[j].compareTo(x);
if (comparison <= 0) {
i = i + 1;
swap(A, i, j);
}
}
swap(A, i + 1, r);
return i + 1;
}
public static void swap(String[] a, int i, int j) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
答案 1 :(得分:1)
查看Quicksort algo of wikipedia,分区算法如下:
// left is the index of the leftmost element of the array
// right is the index of the rightmost element of the array (inclusive)
// number of elements in subarray = right-left+1
function partition(array, 'left', 'right', 'pivotIndex')
'pivotValue' := array['pivotIndex']
swap array['pivotIndex'] and array['right'] // Move pivot to end
'storeIndex' := 'left'
for 'i' from 'left' to 'right' - 1 // left ≤ i < right
if array['i'] < 'pivotValue'
swap array['i'] and array['storeIndex']
'storeIndex' := 'storeIndex' + 1
swap array['storeIndex'] and array['right'] // Move pivot to its final place
return 'storeIndex'
在您的方法中,您不使用pivotIndex
值,而是将pivotValue
基于right
索引。您需要将此参数添加到方法中。
遵循维基算法,它应该是这样的:
public static int partition(String[] A, int p, int r, int pivotIdx) {
String x = A[pivotIdx];
String tmp = A[pivotIdx];
A[pivotIdx] = A[r];
A[r]=tmp;
int i = p;
for (int j=p; j < r; j++) {
int comparison = A[j].compareTo(x);
if (comparison<=0) {
tmp=A[i];
A[i] = A[j];
A[j]=tmp;
i++;
}
}
tmp=A[i];
A[i] = A[r];
A[r]=tmp;
return i;
}