Уменьшить сложность метода быстрой сортировки - PullRequest
0 голосов
/ 06 мая 2018

Привет, ребята, у меня есть вопрос, который я пытаюсь уменьшить сложность этого кода (внизу). Моя идея состояла бы в том, чтобы удалить предложение If в цикле while, но я вроде не смог этого сделать. Здесь я пытаюсь сравнить два элемента SortArray и отсортировать их с помощью алгоритма быстрой сортировки. Цель состоит в том, чтобы сделать алгоритм максимально простым. Меньшие и большие - это индексы, которые проходят через массив и переключаются, если элемент больше, чем точка разворота. Больше в конце в середине, чтобы переключиться с опорой.

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


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

        }

Моя идея состояла в том, чтобы объединить условие цикла while и предложение if в одно, но это не сработало для меня. Я даже попробовал два цикла с одним существом

 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 голосов
/ 06 мая 2018

При правильной реализации средняя сложность быстрой сортировки равна O (NlogN). Проблема в том, что сложность в худшем случае может быть O (N ^ 2), в зависимости от того, как вы выбрали раздел.

Проблема наихудшего случая, когда разбиение последовательно разбивает входной подмассив на 2 подмассива с резко неравными размерами. Если вы неоднократно разбиваете массив N-размера на массивы размера 1 и N-1, то в итоге вы делаете N разбиений. И так как каждый шаг разделения сравнивает все N элементов, вы получаете N * O (N) сравнений; то есть O (N ^ 2).

Так или иначе, решение проблемы наихудшего случая состоит в том, чтобы изменить способ, которым вы выбрали сводную точку ..., чтобы попытаться избежать патологического поведения, когда входные данные уже отсортированы (или почти отсортированы). Вместо того, чтобы выбрать первый элемент в качестве оси, вы можете:

  • случайным образом выбирает стержень
  • выберите трех кандидатов на разворот из разных частей массива и выберите среднюю,
  • 1012 * прочее *

Для записи имеется математическое доказательство того, что алгоритм сортировки, основанный на сравнении, имеет нижнюю границу Ω (NlogN).

Ссылки

...