具有随机和中位数的QuickSort

时间:2014-05-15 05:55:51

标签: java random pivot quicksort

我正在使用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 */

}

2 个答案:

答案 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