两次实施快速排序

时间:2016-01-16 15:20:11

标签: java algorithm quicksort

我有两个快速排序的实现,第一个使用中位数(拳头,中间,最后)作为枢轴,第二个使用中间元素作为枢轴 第一个实施:

public class quickMedian {
     public void sort(int array[]) 
// pre: array is full, all elements are non-null integers
// post: the array is sorted in ascending order
{
    quickSort(array, 0, array.length - 1);              // quicksort all the elements in the array
} 
public void quickSort(int array[], int start, int end)
{
        int i = start;                          // index of left-to-right scan
        int k = end;                            // index of right-to-left scan

        if (end - start >= 1)                   // check that there are at least two elements to sort
        {
                if (array[start+(end-start)/2]>array[end]){
                    swap(array,start+(end-start)/2, end);
                }
                if (array[start]>array[end]){
                    swap(array,start, end);
                }
                if (array[start+(end-start)/2]>array[start]){
                    swap(array, start+(end-start)/2, start);
                }

                int pivot = array[start];       // set the pivot as the first element in the partition

                while (k > i)                   // while the scan indices from left and right have not met,
                {
                        while (array[i] <= pivot && i <= end && k > i)  // from the left, look for the first
                                i++;                                    // element greater than the pivot
                        while (array[k] > pivot && k >= start && k >= i) // from the right, look for the first
                            k--;                                        // element not greater than the pivot
                        if (k > i)                                       // if the left seekindex is still smaller than
                                swap(array, i, k);                      // the right index, swap the corresponding elements
                }
                swap(array, start, k);          // after the indices have crossed, swap the last element in                                               // the left partition with the pivot 
                quickSort(array, start, k - 1); // quicksort the left partition
                quickSort(array, k + 1, end);   // quicksort the right partition
        }
        else    // if there is only one element in the partition, do not do any sorting
        {
                return;                     // the array is sorted, so exit
        }
}

public void swap(int array[], int index1, int index2) 
// pre: array is full and index1, index2 < array.length
// post: the values at indices 1 and 2 have been swapped
{
    int temp = array[index1];           // store the first value in a temp
    array[index1] = array[index2];      // copy the value of the second into the first
    array[index2] = temp;               // copy the value of the temp into the second
}


}

第二个实施:

public class quickSort {
      private int array[];
    private int length;

    public void sort(int[] inputArr) {

        if (inputArr == null || inputArr.length == 0) {
            return;
        }
        this.array = inputArr;
        length = inputArr.length;
        quickSorter(0, length - 1);
    }

    private void quickSorter(int lowerIndex, int higherIndex) {

        int i = lowerIndex;
        int j = higherIndex;

        // calculate pivot number, I am taking pivot as middle index number
        int pivot = array[lowerIndex+(higherIndex-lowerIndex)/2];
        // Divide into two arrays
        while (i <= j) {
            /**
             * In each iteration, we will identify a number from left side which
             * is greater then the pivot value, and also we will identify a number
             * from right side which is less then the pivot value. Once the search
             * is done, then we exchange both numbers.
             */
            while (array[i] < pivot) {
                i++;
            }
            while (array[j] > pivot) {
                j--;
            }
            if (i <= j) {
                exchangeNumbers(i, j);
                //move index to next position on both sides
                i++;
                j--;
            }
        }
        // call quickSort() method recursively
        if (lowerIndex < j)
            quickSorter(lowerIndex, j);
        if (i < higherIndex)
            quickSorter(i, higherIndex);
    }

    private void exchangeNumbers(int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

}

要获得中位数,我们需要在每次递归时执行额外的步骤,这可能会增加一点的时间(如果数组是完全随机的)。

我在随机生成的大小为N=10,000,000的数组上测试这两个类,我已经多次完成测试,第一次执行需要大约30秒,第二次大约需要4秒 所以这显然不是由获得三个数字中位数的额外开销造成的。

第一次实施肯定有问题,它是什么?

这是测试代码:

 public static void main(String[] args) {
    File number = new File ("f.txt");
    final int size = 10000000;

    try{
   //  quickSort s = new quickSort();
     quickMedian s = new quickMedian();
    writeTofile(number, size);
  int [] arr1 =readFromFile(number, size);
    long a=System.currentTimeMillis();
    s.sort(arr1);
    long b=System.currentTimeMillis();
    System.out.println("quickSort: "+(double)(b-a)/1000);
    }catch (Exception ex){ex.printStackTrace();}


 }

0 个答案:

没有答案