Изменения

Перейти к: навигация, поиск

Таблица инверсий

542 байта убрано, 00:05, 13 января 2012
Алгоритм построения
if P[j] > P[i]
T[P[i]] = T[P[i]] + 1
Сложность данного алгоритма {{---}} <tex>O(n^2)</tex>. Уменьшить время работы можно используя [[Дерево отрезков. Построение|дерево отрезков]]алгоритм, похожий на сортировку слиянием.
Получим из исходной Пусть дано разбиение перестановки обратную и запишем её в массив <tex>M</tex>. Также заведём массив <tex>S</tex> длиной <tex>n</tex>на два списка, инициализированный нулями. После обработки <tex>i</tex>-го причём для каждого элемента будем вносить значение 1 в ячейку <tex>S[M[i]]</tex>. Обработку начинаем дано число инверсий слева с последнего элемента элементами того же списка и двигаемся к началу. Пустьизвестно, функция <tex>Sum(i)</tex> возвращает значение суммы элементов массива <tex>S</tex> от 1 до <tex>i</tex>что все числа первого списка стоят левее всех чисел второго списка в исходной перестановке. Тогда <tex>i</tex>-й элемент таблицы Будем считать количество инверсий находится такслева элементов обоих списков следующим образом: <tex>T[i] = Sum(M[i])</tex> сливаем списки, аналогично сортировке слиянием.
Данная формула даёт правильный ответ, так как <tex>S[M[i]]</tex> содержит единицу только Если в том случаерезультат нужно записать элемент первого списка, если мы уже обработали элементто все нерассмотренные элементы второго списка больше, стоящий в <tex>M[i]</tex>-й позиции. Так как обработка идёт от больших чисел к меньшимследовательно, <tex>Sum(M[i])</tex> выдаст нужное нам количество чиселинверсий для этого элемента не меняется. Если в результат нужно записать элемент второго списка, больших <tex>i</tex> то все нерассмотренные элементы первого списка больше его и стоящих в перестановке стоят левее него. Следовательно, количество инверсий для этого элемента следует увеличить на количетво нерассмотренных элементов второго списка.
Функция <tex>Sum</tex> реализуется с помощью [[Дерево отрезков. Построение|дерева отрезков]]. Каждое изменение массива и обращение к функции <tex>Sum</tex> влечёт за собой <tex>\log_2n</tex> операций. Таким Описанный алгоритм записывается в псевдокод следующим образом получаем сложность алгоритма <tex>O(n\log_2n)</tex>:
Также существует достаточно простой алгоритм построения таблицы инверсий с использованием def inverses_merge(ls1, ls2): result = [] it1, it2 = 0, 0 while (it1 < len(ls1)) and (it2 < len(ls2)): if ls1[Сортировка слиянием|сортировки слияниемit1].item < ls2[it2]. Вначале выписываются следующие упорядоченные пары чиселitem: в <tex>i</tex> result.append(ls1[it1]) it1 += 1 else: result.append(item = ls2[it2].item, inverses = ls2[it2].inverses + len(ls1) -ой паре на первом месте стоит it1) it2 += 1 while (it1 <tex>ilen(ls1)): result.append(ls1[it1]) it1 += 1 while (it2 </tex>-й элемент перестановки, а на втором {{---}} 0len(ls2)): result. Далее применяется append(ls2[it2]) it2 += 1 return result def inverses_get(ls): if len(ls) == 1: return [Сортировка слиянием|сортировка слиянием(item = ls[0], inverses = 0)] else: return inverses_merge(inverses_get(ls.first_half), при чем при выписывании элемента из второй цепочки упорядоченных парinverses_get(ls.second_half)) * inverses_merge — процедура, число на второй позиции в данном элементе увеличивается на количество элементов, оставшихся в первой цепочке. В конце сортировки получим цепочку упорядоченных пар. Выписывая вторые элементы данных упорядоченных сливающая два списка пар* inverses_get — процедура, получим искомую рекурсивно получающая таблицу инверсий. для перестановки Сложность данного представленного алгоритма совпадает со сложностью [[Сортировка слиянием|сортировки слиянием]] и составляет есть <tex>O(n\log_2nlog_2 n)</tex>. Алгоритм с такой же сложностью можно построить с помощью дерева отрезков.
= Алгоритм восстановления =
304
правки

Навигация