16
March

Быстрая сортировка на Java (Quick Sort)

Posted in: Java technologies, J2SE |

Алгоритм Quick Sort является одним из самых быстрых алгоритмов сортировки. Его среднее время выполнения - O(n log n). Quick Sort реализуется с помощью рекурсии.
В этой статье представлен демонстрационный пример алгоритма быстрой сортировки на Java.

Суть алгоритма заключается в следующем. Берется некоторый элемент массива (желательно рандомом, чтобы алгоритм выполнялся приблизительно одинаковые промежутки времени для любых наборов данных). Элементы, которые находятся слева и больше по значению чем первоначальный, меняются местами с элементами, которые находятся справа и меньше первоначального. Аналогичная операция выполняется для наборов данных слева и справа от начального. И так далее по рекурсии.
А вот собственно и реализация на Java:

import java.util.Random;

public class QuickSortExample {
    public static int ARRAY_LENGTH = 30;
    private static int[] array = new int[ARRAY_LENGTH];
    private static Random generator = new Random();

    public static void initArray() {
        for (int i=0; i<ARRAY_LENGTH; i++) {
            array[i] = generator.nextInt(100);
        }
    }

    public static void printArray() {
        for (int i=0; i<ARRAY_LENGTH-1; i++) {
            System.out.print(array[i] + “, ”);
        }
        System.out.println(array[ARRAY_LENGTH-1]);
    }

    public static void quickSort() {
        int startIndex = 0;
        int endIndex = ARRAY_LENGTH - 1;
        doSort(startIndex, endIndex);
    }

    private static void doSort(int start, int end) {
        if (start >= end)
            return;
        int i = start, j = end;
        int cur = i - (i - j) / 2;
        while (i < j) {
            while (i < cur && (array[i] <= array[cur])) {
                i++;
            }
            while (j > cur && (array[cur] <= array[j])) {
                j–;
            }
            if (i < j) {
                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
                if (i == cur)
                    cur = j;
                else if (j == cur)
                    cur = i;
            }
        }
        doSort(start, cur);
        doSort(cur+1, end);
    }

    public static void main(String[] args) {
        initArray();
        printArray();
        quickSort();
        printArray();
    }
}

Данная программа работает правильно, но наверняка ее можно немного оптимизировать.
Если у вас есть замечания или вопросы по поводу моей реализации алгоритма, буду рад выслушать вас.

9 Comments »

RSS feed for comments on this post. TrackBack URI



March 16, 2006 #

Зачем оно тебе надо?

java.util
Class Collections

java.lang.Object
extended by java.util.Collection

public class Collections
extends Object

This class is a member of the Java Collections Framework.

sort(List) - Sorts a list using a merge sort algorithm, which provides average-case performance comparable to a high-quality quicksort, guaranteed O(n*log n) performance (unlike quicksort), and stability (unlike quicksort). (A stable sort is one that does not reorder equal elements.)

public static > void sort(List list)

Parameters:
list - the list to be sorted.
Throws:
ClassCastException - if the list contains elements that are not mutually comparable (for example, strings and integers).
UnsupportedOperationException - if the specified list’s list-iterator does not support the set operation.

March 16, 2006 #

Олег, ты хоть книгу Кнута “Сортировка и Поиск” так не комментируй :).
Если уж на то пошло, то и для класса Array этот алгоритм реализован.
Назначение статьи - объяснить тем, кто не знаком с алгоритмом, как он работает и как его можно реализовать.

kontiky
June 8, 2006 #

Joshua Bloch открывает нам глаза на binarysearch алгоритм.
Look here
Есть ошибки даже там

Asf
June 9, 2006 #

В качестве учебного примера неплохо.
Единственное замечание - на последних эатапх, когда длина последовательносьти становиться меньше определнного числа (обычно принимают или 8 или 16 элементов), переход с quicksort на другой алгоритм (пусть даже на пузырек) дает существенный выигрышь с скорости.
Это описано в Лорин “Сортировка и алгоритмы сортировки”. Есть ли это в Кнуте - не помню.

June 9, 2006 #

2kontiky: Ну так у меня это учитывается…
2Asf: спасибо большое за информацию. Я этого не знал.

jonie
December 13, 2006 #

Мужики, j- замените на j–
А так вроде должно работать)

jonie
December 13, 2006 #

гы) на j минус-минус. Чет парсер сайта глюкавит?

Stas
January 28, 2008 #

Чтото я непонял смысл строки

int cur = i - (i - j) / 2;

Если j>i то в скобке будет -, следно все это эквивалентно:

int cur =i+(j-i)/2;

не так ли? Или в этом есть своя хитрость?

January 28, 2008 #

Привет.
i - (i - j)/2 = i - i/2 + j/2 = i/2 + j/2 = (i + j)/2
Смысл в том, что для большИх i и j может быть overflow, если их сумма больше Integer.MAX_VALUE.
Соответственно среднее арифметическое может быть посчитано неправильно. А нам это ну никак не надо :).

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>