降低Quicksort方法的复杂性

时间:2018-05-06 12:18:06

标签: java while-loop complexity-theory quicksort partition

嘿伙计我有一个问题我正试图降低此代码的复杂性(在底部)。我的想法是删除while循环中的If子句但我没有做到这一点。我在这里要做的是比较SortArray的两个元素并使用Quicksort算法对它们进行排序。目标是使算法尽可能简单。较小和较大的是遍历数组的索引,如果元素大于枢轴,则切换。更大的是在中间的末端与枢轴切换。

   if (records.getElementAt(smaller).compareTo(Pivot) > 0 ) {


        swap(records, smaller, bigger);
        bigger--;

        }

我的想法是将while循环和if子句的条件合并为一个,但这对我没用。我甚至尝试了两个while循环,其中一个是

 while (smaller <= bigger && records.getElementAt(smaller).compareTo(Pivot)>0 

和另一个

while (smaller <= bigger && records.getElementAt(smaller).compareTo(Pivot)<0

但这也没有用。

import frame.SortArray;

public class QuickSortA extends QuickSort {

/**
 * Quicksort algorithm implementation to sort a SorrtArray by choosing the
 * pivot as the first (leftmost) element in the list
 * 
 * @param records
 *            - list of elements to be sorted as a SortArray
 * @param left
 *            - the index of the left bound for the algorithm
 * @param right
 *            - the index of the right bound for the algorithm
 * @return Returns the sorted list as SortArray
 */
@Override
public void Quicksort(SortArray records, int left, int right) {
    // TODO
    // implement the Quicksort A algorithm to sort the records
    // (choose the pivot as the first (leftmost) element in the list)
    if (left < right) {
    int a = Partition(records, left, right);
        Quicksort(records, left, a - 1);
        Quicksort(records, a + 1, right);
    }   

}   

public static int Partition(SortArray records, int left, int right) {

    int smaller = left + 1;
    int bigger  = right;
    SortingItem Pivot = records.getElementAt(left);


    while (smaller <= bigger ) {

        if (records.getElementAt(smaller).compareTo(Pivot) > 0 ) {


            swap(records, smaller, bigger);
            bigger--;

            }

        else

            smaller++;                
        }
    swap(records, bigger, left);    
    return bigger;





}

public static void swap(SortArray records, int small, int big) {
    SortingItem Tauschvariable;
    Tauschvariable = records.getElementAt(small);
    records.setElementAt(small, records.getElementAt(big));
    records.setElementAt(big, Tauschvariable);
}

// You may add additional methods here

}

public class SortArray {

private int numberOfItems;

private ArrayList<SortingItem> listOfItems;

private int readingOperations;
private int writingOperations;

/**
 * @param numberOfItems
 *            number of items to hold
 */
public SortArray(ArrayList<String[]> items) {
    numberOfItems = items.size();
    readingOperations = 0;
    writingOperations = 0;
    listOfItems = new ArrayList<>();

    for (String[] element : items) {
        SortingItem s = new SortingItem();
        s.BookSerialNumber = element[0];
        s.ReaderID = element[1];
        s.Status = element[2];
        listOfItems.add(s);
    }
}

1 个答案:

答案 0 :(得分:0)

正确实施后,快速排序的平均复杂度为O(NlogN)。问题是最坏情况的复杂性可能是O(N ^ 2),具体取决于您选择分区的方式。

当分区始终将输入子阵列分成两个具有极大不等大小的子阵列时的最坏情况问题。如果您反复将N大小的数组拆分为大小为1和N-1的数组,那么最终会进行N次拆分。由于每个分区步骤都比较了所有N个元素,因此最终得到N * O(N)个比较;即O(N ^ 2)。

无论如何,最坏情况问题的解决方案是改变你选择枢轴的方式......当输入已经排序(或几乎排序)时,试图避免病态行为。而不是选择第一个元素作为枢轴,你可以:

  • 随机选择枢轴
  • 从阵列的不同部分选择三个枢轴候选者,然后选择中间的
  • 诸如此类

为了记录,有一个数学证明,基于比较的排序算法具有下限Ω(NlogN)。

参考文献: