我正在使用QuickSort进行一项任务,以显示使用不同方法获取Pivot时算法的速度,如随机或三个中位数。到目前为止,当使用随机或中位数我得到不同的输出并且没有一个被排序时,我无法弄清楚我的错误是什么。我去了互联网上的每一个地方。有人能看着它并告诉我我在这里做错了吗?
以下是QuickSort代码:
import java.util.*;
public class QuickSort {
public static void main(String[] args) {
int[] arr = {5, -32, 12, 43, 88, 19, 113, 62, -11, 2};
System.out.println(Arrays.toString(arr));
quickSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr) {
quickSort1(arr, 0, arr.length -1);
}
private static void quickSort1(int[] list, int first, int last) {
if (first < last) {
int pivotLocation = partition(list, first, last);
quickSort1(list, first, pivotLocation - 1);
quickSort1(list, pivotLocation + 1, last);
}
}
private static int partition(int[] list, int first, int last) {
int pivot;
int smallIndex;
Random rand = new Random();
int num = rand.nextInt(list.length);
swap(list, first, (first + last) / 2);
pivot = list[first];
//pivot = medianOfThree(list, first, last);
//pivot = list[num];
smallIndex = first;
for (int index = first + 1; index <= last; index++) {
if (list[index] < pivot) {
smallIndex++;
swap(list, smallIndex, index); // Should we limit to if(smallIndex != index)
}
}
swap(list, first, smallIndex);
return smallIndex;
}
private static void swap(int[] list, int first, int second) {
int temp;
temp = list[first];
list[first] = list[second];
list[second] = temp;
}
private static int medianOfThree(int[] arr, int first, int last) {
int f = arr[first], l = arr[last], m = arr[(last + first)/2];
if(l <= f && l >= m || l >= f && l <= m)
return l;
else if (m <= f && m >= l || m >= f && m <= l)
return m;
return f;
}
}
我尝试使用while()
它速度更快,但我必须通过循环100次以上来测试排序的速度,这给了我java.lang.StackOverflowError
。
任何建议都会有所帮助。
编辑: 我已经修正了中位数方法和随机方法,感谢您的帮助。
我正在研究while循环,我想到了如何让它正常工作和排序。现在的问题是,每当我尝试制作大型数组来测试排序的速度时,它就会得到堆栈而且我不确定(我的意思是10,000个元素)。
我从另一个程序中调用该类,但它仍未按预期工作。
这里是分区方法,类是相同的:
private static int partition(int[] list, int first, int last) {
Random rand = new Random();
int pivot = 0;
int num = first + rand.nextInt(last - first + 1);// generates random index
pivot = medianOfThree(list, first, last); //finding median of three numbers
//pivot = list[first]; //using the first data as pivot
//pivot = list[num]; //Random index value is used as pivot
int leftPointer= first ;
int rightPointer = last ;
//swap(list, last, (first+last)/2);
while(true) {
while (list[leftPointer] < pivot)
leftPointer++;
while (rightPointer > 0 && list[rightPointer] > pivot)
rightPointer--;
if(leftPointer >=rightPointer)
break;
swap(list, leftPointer, rightPointer);
//count++;
//System.out.println(Arrays.toString(list)+ "switch"+ count );
}
//System.out.println(Arrays.toString(list));
//swap(list, last, leftPointer);
//System.out.println(leftPointer);
return leftPointer;
}
编辑:
这是我用来测试排序效率的测试代码,QuickSort
使用while
循环仍然无法正常工作,我做错了什么?
测试代码:
import java.util.*;
public class Test {
public static final int ARRAYSIZE = 50000; // Test array element count
public static final int ELEMENTSIZE = 10000; // Test array element size
public static final int LOOPS = 1000;
public static void main(String[] args) {
long t1=0,t2=0,t3=0;
long c1=0,c2=0; // Counters
for(int test = 1; test <= LOOPS; test++) {
System.out.print(test + "..");
Random rand = new Random();
int[] arr1 = new int[ARRAYSIZE];
for(int i = 0; i < ARRAYSIZE; i++) // Generate a random array with ARRAYSIZE elements
arr1[i] = rand.nextInt(ELEMENTSIZE);
int[] arr2 = Arrays.copyOf(arr1, arr1.length); // Use an exact array copy for each sorting test
int[] arr3 = Arrays.copyOf(arr1, arr1.length);
t1 = System.currentTimeMillis();
QuickSort.quickSort(arr1); //Run & Time Quick Sort
t2 = System.currentTimeMillis();
Arrays.sort(arr3); //Run & Time Arrays.sort
t3 = System.currentTimeMillis();
c1 += t2-t1;
c2+=t3-t2;
}
System.out.println();
System.out.println("Quick Sort took: " + c1/LOOPS + " milliseconds");
System.out.println("Arrays.sort took: " + c2/LOOPS + " milliseconds");
}
/* ADD YOUR CODE HERE */
}
答案 0 :(得分:0)
int num = first + rand.nextInt(last - first + 1);
中间元素的中位数为:
int m = arr[(last + first)/2];
我建议您使用调试器运行该程序,并在每个步骤之后说服自己完成正确的操作。
答案 1 :(得分:0)
我发现了代码的问题,每当它比较完全相同的值时,它会不断切换并再次比较它们......所以我提出了一个条件来在发生这种情况时打破循环。 我用过:
if(leftPointer >=rightPointer || list[leftPointer]== list[rightPointer])
break;
else
swap(list, leftPointer, rightPointer);
而不是:
if(leftPointer >=rightPointer)
break;
else
swap(list, leftPointer, rightPointer);
排序正常。
-Thanks