Поиск k-ой порядковой статистики — различия между версиями
 (→Код алгоритма)  | 
				м (rollbackEdits.php mass rollback)  | 
				||
| (не показаны 3 промежуточные версии 3 участников) | |||
| Строка 10: | Строка 10: | ||
* '''k = m'''. Порядковая статистика найдена.  | * '''k = m'''. Порядковая статистика найдена.  | ||
| − | * '''k < m'''. Рекурсивно ищем <tex>k</tex>-ую статистику в первой   | + | * '''k < m'''. Рекурсивно ищем <tex>k</tex>-ую статистику в первой части массива.  | 
| − | * '''k > m'''. Рекурсивно ищем <tex>(k - m - 1)</tex>-ую статистику во второй   | + | * '''k > m'''. Рекурсивно ищем <tex>(k - m - 1)</tex>-ую статистику во второй части массива.  | 
=== Код алгоритма ===  | === Код алгоритма ===  | ||
| − | Ниже представлен код представленного алгоритма. При реализации, однако, вместо рекурсивных вызовов изменяются границы поиска статистики во внешнем цикле. В коде считаем, что процедура '''partition''' принимает массив и границы отрезка, который будет рассечён (причём правая граница отрезка не включается) и возвращает индекс опорного элемента. Также  | + | Ниже представлен код представленного алгоритма. При реализации, однако, вместо рекурсивных вызовов изменяются границы поиска статистики во внешнем цикле. В коде считаем, что процедура '''partition''' принимает массив и границы отрезка, который будет рассечён (причём правая граница отрезка не включается), и возвращает индекс опорного элемента. Также считается, что массив индексируется с нуля.  | 
  '''int''' findOrderStatistic('''int[]''' array, '''int''' k) {  |   '''int''' findOrderStatistic('''int[]''' array, '''int''' k) {  | ||
Текущая версия на 19:43, 4 сентября 2022
| Определение: | 
| -ой порядковой статистикой набора элементов линейно упорядоченного множества называется такой его элемент, который является -ым элементом набора в порядке сортировки | 
Содержание
Модификация QuickSort
Описание алгоритма
Будем использовать процедуру рассечения массива элементов из алгоритма сортировки QuickSort. Пусть нам надо найти -ую порядковую статистику, а после рассечения опорный элемент встал на позицию . Возможно три случая:
- k = m. Порядковая статистика найдена.
 - k < m. Рекурсивно ищем -ую статистику в первой части массива.
 - k > m. Рекурсивно ищем -ую статистику во второй части массива.
 
Код алгоритма
Ниже представлен код представленного алгоритма. При реализации, однако, вместо рекурсивных вызовов изменяются границы поиска статистики во внешнем цикле. В коде считаем, что процедура partition принимает массив и границы отрезка, который будет рассечён (причём правая граница отрезка не включается), и возвращает индекс опорного элемента. Также считается, что массив индексируется с нуля.
int findOrderStatistic(int[] array, int k) {
  int left = 0, right = array.length;
  while (true) {
    int mid = partition(array, left, right);
    if (mid == k) {
      return array[mid];
    }
    else if (k < mid) {
      right = mid;
    }
    else {
      left = mid + 1;
    }
  }
}
Анализ времени работы
Аналогично QuickSort, может возникнуть такой же худший случай (процедура partition возвращает каждый раз левую или правую границу рассматриваемой части), при котором время работы составит . Однако, если считать, что partition возвращает все элементы рассматриваемого отрезка с равной вероятностью, то можно оценить матожидание времени работы как .
Будем оценивать количество сравнений. При поиске статистики в массиве размера функция partition (точнее, одна из распространённых вариаций) совершает не более сравнений. Далее, в зависимости от выбирается левая или правая половины (или вообще алгоритм завершает работу). Оценку проводим сверху, то есть, будем считать, что каждый раз выбирается большая половина.
Предположим, что для некоторой константы и всех (будем доказывать оценку по индукции). Тогда верно неравенство:
Преобразуем сумму из правой части равенства по формуле суммы арифметической прогрессии и оценим преобразованное выражение:
Воспользуемся полученной оценкой для оценки исходного выражения. Также, предположим, что :
Для довершения доказательства необходима проверка базы индукции, но она тривиальна: для выборки порядковой статистики из одного элемента сравнений не требуется: . Итого, мы доказали, что , следовательно,
Ссылки
- Selection algorithm — Wikipedia
 - Donald Knuth. The Art of Computer Programming, Volume 3: Sorting and Searching, Third Edition. Addison-Wesley, 1997. ISBN 0-201-89685-0. Section 5.3.3: Minimum-Comparison Selection, pp.207–219.