Обсуждение:Быстрая сортировка

message: "Хоар разработал этот метод применительно к машинному переводу": источник - личный разговор с Ч. Э. Р. Хоаром. Mercury 20:17, 31 августа 2006 (UTC)
Предлагаю добавить замечание по практической реализации алгоритма: способ(ы) избежания рекурсии, например.--93.120.155.69 14:20, 5 марта 2008 (UTC)

message: К сожалению, версия на C работает неправильно. 62.117.90.1 10:54, 21 сентября 2006 (UTC)
Для чего здесь столько (уже 13) примеров реализации на различных языках? Скорее захламляют, чем улучшают статью. Предлагаю убрать, оставив 2-3 реализации. -- NZeemin 11:06, 24 ноября 2006 (UTC)
Пока закоментировал некоторые.... Ors archangel 13:50, 15 марта 2007 (UTC)
Алгоритм наглядно предствлен в ..видеоролике (английская редакция)!А программная реализация его -дело вкуса и не должно вызвать трудностей.
Предлагаю добавить реализацию на Brainfuck --194.44.198.45 14:24, 20 сентября 2007 (UTC)
исправил алгоритм на Си. точно работает (сам проверял). по сути это вариант из книги Сэджвика, только немного упрощённый. 83.237.48.206 19:28, 23 февраля 2008 (UTC)
Пример на Java не работает, индекс выходил за пределы границ массива. 84.51.116.134 13:03, 16 июля 2012 (UTC)
Пример на java, с, с++ и c# если передать массив {1,2}, а значения low = 0, high = 1, то будет стэковерфлоу, так как вызовется ровно с теми же параметрами
     int i = low;    // = 0      
     int j = high;  // = 1
     int x = A[(low+high)/2];  // = 1
     do {
          while(A[i] < x) ++i;  // 1 < 1 - false
          while(A[j] > x) --j;   // 2 > 1 - true, j = 0
          if(i <= j){    // 0 == 0
               Обменяли A[0] и A[0]
               i = 1
               j = 1
     } while(i < j); // 1 < 1 - false
     if(low < j) qSort(A, low, j);  - вызвали с теми же аргументами ({1,2}, 0,1)
----------------
Правильно ли передаются параметры в примере для С? Там указано: qsort(a, 0, N); - но при этом, далее запрашивается элемент массива: a[ N ] - которого в массиве быть не может (нумерация с нуля).
Должно быть qsort( a, 0, N - 1 ); ?
109.194.220.245 19:31, 14 сентября 2015 (UTC) Гость.
thread_title:  Примеры реализации 

message: Текущая версия quicksort на Прологе:
 quicksort([], X, X).
 
 quicksort([H|T], S, X) :-
   split(H, T, A, B),
   quicksort(A, S, [H|Y]),
   quicksort(B, Y, X).
Я не только не смог понять смысл и назначение дополнительного (не знаю даже, второго или третьего) аргумента, но и не смог даже запустить этот вариант на Прологе, предполагая самые разнообразные назначения этих двух последних аргументов. Первый аргумент - судя по всему, исходный список...
В моём варианте, по сравнению со старым, я ввёл дополнительные два предиката - middle и append.
append - для того, чтобы повысить читаемость программы (то есть, теперь есть полное соответствие алгоритму быстрой сортировки: мы делим список на две части, сортируем эти два части по отдельности и потом собираем два отсортированных списка в один), в отличие от старой версии (когда список делился на две части, а потом с обоими частями производились непонятные телодвижения)
middle - чтобы в качестве разделителя выбирать центральный элемент списка, а не первый. Выбор первого элемента списка в качестве разделителя приводит ко времени сортировки О(n*n) для уже отсортированных списков.
Вспомогательные предикаты:
 /* 
   middle(L, L, X, L1)
   Находит в списке L центральный элемент и
   возвращает его в Х и список без  него в L1.
   В первом аргументе L убираем по два элемента,
   а во втором аргументе L - по одному элементу.
   Фиксируем факт нахождения среднего элемента,
   если первый аргумент - пустой или содержит в себе
   ровно один элемент.
 */
 middle([],[X|T],X,T).
 middle([_],[X|T],X,T).
 middle([_,_|T1],[H2|T2],X,[H2|T3]):-
   middle(T1,T2,X,T3).
 
 /* 
   split(X, L, A, B)
   Разбивает список L на два подсписка A и B так, что
   все элементы А меньше Х, а все элементы В больше Х.
   (Куда добавляются элементы, равные Х, не имеет 
   значения для алгоритма сортировки. 
   Здесь они (к примеру) добавляются в В.)
 */
 split(_, [], [], []).
 split(H, [A|X], [A|Y], Z) :-
   /* используем механизм отсечений, чтобы не проверять дважды */
   order(A, H), !,
   split(H, X, Y, Z).
 /* это правило может быть применено только в случае, 
    если not(order(A, H)) - благодаря 
    использованному отсечению это перепроверять не нужно */
 split(H, [A|X], Y, [A|Z]) :-
   split(H, X, Y, Z).
 
 /*
   append(X,Y,L)
   Соединяет два списка в один.
   Берём Х, добавляем в конец Y, получаем L.
 */
 append([],X,X).
 append([H|T],X,[H|T1]):-
   append(T,X,T1).
 
 /*
   qsort(X,Y)
   Быстрая сортировка.
   Х - исходный список,
   Y - результат
 */
 /* если сортируем пустой список, то 
    результат - пустой список
 */
 qsort([], []).
 
 qsort(L, X) :-
   /* собственно, алгоритм быстрой сортировки. */
   /* находим центральный элемент и удаляем его */
   middle(L,L,M,L1),
   /* центральный элемент будет разделителем.
      разбиваем спискок без элемента-разделиеля на два списка.
   */
   split(M, L1, A, B),
   /* сортируем по очереди оба списка */
   qsort(A, X1),
   qsort(B, X2),
   /* соединяем отсортированные списки в один.
      не забываем поставить разделитель на место.
   */
   append(X1,[M|X2],X).
если убрать предикат middle и в качестве разделителя всегда выбирать самый первый элемент списка, то второе утверждение для qsort будет таким
 qsort([H|T], X) :-
   split(H, T, A, B), /*делим*/
   qsort(A, X1), /*сортируем*/
   qsort(B, X2), /*сортируем*/
   append(X1,[H|X2],X). /*соединяем*/
Не стал вставлять из-за вопросов о количестве реализаций. Но оставил здесь, так как эта реализация может вызвать интерес, думаю, в первую очередь у тех, кто изучает язык Пролог --Yuri Popoff 00:24, 3 декабря 2007 (UTC)
thread_title:  Пример на Прологе не работает 

message: в описании алгоритма
пункт 6: 
    если l < r — найденную пару элементов нужно обменять...
Разве должно быть l < r? Может всетаки l > r?
--- 93.84.241.55 10:03, 1 августа 2008 (UTC)
* Нет, это условие правильное. Индексы l и r указывают на концы разделеных фрагментов; если бы l>r то разделение завершается. --CiaPan 08:14, 27 апреля 2016 (UTC)
thread_title:  Подозрительное условие 

message: Предлагаю заменить в пункте 2.6 фразу "значение m изменяется на r-й или l-й элемент соответственно" на "значение m изменяется на r или l соответственно". Ибо m - это индекс опорного элемента, и предложение заменить его на l-й элемент несколько некорректно.
91.199.143.34 10:49, 8 декабря 2010 (UTC)
Кто-нибудь может привести пример входных данных, когда quicksort работает с выбором медианы и работает неправильно?
Всегда считал, что не может выбор опорного элемента влиять на корректность. На производительность, да.
88.201.200.66 16:56, 23 марта 2009 (UTC)
thread_title:  Корректность алгоритма и выбор опорного элемента 

message: На рисунке "Быстрая сортировка" неправильная последовательность действий: после первого шага указано что поменяются местами элементы "5" и "4", хотя, по описанному алгоритму, должны меняться элементы "7" и "4". 
Судя по всему картинка была взята с английской статьи (подпись под картинкой "In-place partition in action on a small list. The boxed element is the pivot element, blue elements are less or equal, and red elements are larger.") без особого рассмотрения её (там описывается какой-то вариант алгоритма, в котором опорный элемент в начале процедуры разбития массива перемещается на последнее место). 
Предлагаю заменить эту картинку на картинку с той же английской статьи (подпись под картинкой "Full example of quicksort on a random set of numbers. The boxed element is the pivot. It is always chosen as the last element of the partition.")
replies: text: Обе эти иллюстрации предназначены для модифицированного алгоритма, а не оригинального. --Кыс 19:37, 22 июня 2010 (UTC)
thread_title:  На рисунке неправильная последовательность действий алгоритма 

message: "Базой рекурсии являются наборы, состоящие из одного или двух элементов. Первый возвращается в исходном виде, во втором, при необходимости, сортировка сводится к перестановке двух элементов."
Это неверно, базой являются наборы из нуля и одного элемента. Набор из двух может обрабатываться общим случаем.
thread_title:  База рекурсии 

message: Ребята, какое МГУ? Википедия, мда. 109.184.166.165 22:31, 13 августа 2013 (UTC)
replies: text: Такое МГУ. Вполне обычное. А что? --dm обсужд. 00:30, 14 августа 2013 (UTC)
replies: text: : А, да, посмотрел, действительно МГУ, удивительно. 95.79.49.191 08:46, 14 августа 2013 (UTC)
thread_title:  ...разработанный английским информатиком Чарльзом Хоаром в МГУ в 1960 году. 

message: Функция partition, описанная в пункте 2.1 "Общий механизм сортировки", может уходить в бесконечный цикл. Рассмотрим работу функции на следующий входных данных: A = [0, 1, 2, 3, 8, 5, 6, 7, 8, 9, 10], lo = 0, hi = 10. Предположим, что фукнция get_pivot вернула значение 8. После выполнения цикла на строках 6-7 переменная i будет иметь значение 4. После выполнения цикла на строках 8-9 переменная j будет иметь значение 8. С этого момента цикл на строках 5-11 будет бесконечно обменивать значения элементов A[4] и a[8].
Автор сообщения: i876g35s1r 93.125.107.34 06:37, 15 августа 2017 (UTC)
replies: text: Википедия - не фонд алгоритмов и программ. Приведенный фрагмент кода - это иллюстрация, а не программный продукт. --KVK2005 (обс.) 10:14, 15 августа 2017 (UTC)
replies: text: : Хоть это и пример, но он не верен. Для если после swap A[i] with A[j] дописать i := i + 1, j := j - 1 это должно исправить наблюдаемый баг. Изменения сделал  --IDIB (обс.) 12:49, 2 сентября 2017 (UTC)

text: --Well-Informed Optimist (?•!) 14:51, 26 сентября 2017 (UTC)
(UTC)
thread_title:  Сообщение об ошибке 

message: Там рекурсия вызывается по подмассивам, включащим разрешающий элемент. В английской вики это написано, в российской нет.
Должно быть:
quicksort(A,lo,p);
quicksort(A,p+1,hi); 
 Supervisual (обс.) 19:15, 23 октября 2018 (UTC)
thread_title:  Разбиение Хоара 

message: Не пойму оценку под анимацией в лучшем случае:
Лучшее время	O(n log n) (обычное разделение)
или O(n) (разделение на 3 части)
185.67.55.10 20:34, 7 ноября 2018 (UTC) Юрий.
В статье нет ничего про оценку по времени в О(n).
Возможна она только если следить были ли перестановки и в случае их отсутствия не вызывать следующий шаг. Конечно на отсортированном массиве и при выборе средним опорного элемента. Но в тексте про это ничего не вижу. 185.67.55.10 20:34, 7 ноября 2018 (UTC)
Про разделение на 3 части действительно ничего нет. описан принцип действия такой сортировки  --IDIB (обс.) 11:32, 9 ноября 2018 (UTC)
thread_title:  Время работы алгоритма