Изменения

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

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

1614 байт добавлено, 04:39, 21 ноября 2011
Алгоритм восстановления
}}
=== Алгоритм построения ===
Таблицу инверсий тривиально построить по определению. Для каждого элемента перестановки считаем количество элементов, больших данного и стоящих в перестановке левее него.
Сложность данного алгоритма {{---}} $O(n^2)$. Уменьшить время работы можно используя [[Дерево отрезков. Построение|дерево отрезков]].
Отсортируем элементы перестановки, сохраняя индексы. Массив $M$ будет содержать номер позиции каждого элемента в исходной перестановке. Также заведём массив $S$ длиной $n$, инициализированный нулями. После обработки $i$-го элемента будем вносить значение 1 в ячейку $S[M[i]]$. Обработку начинаем с последнего элемента и двигаемся к началу. Пусть, функция $Sum(i)$ возвращает значение суммы элементов массива $S$ от 1 до $i$ включительно. Тогда $i$-й элемент таблицы инверсий находится так:
$T[i] = Sum(M[i])$
Функция Sum реализуется с помощью [[Дерево отрезков. Построение|дерева отрезков]]. Каждое изменение массива и обращение к функции $Sum$ влечёт за собой $log_2 n$ операций. Таким образом получаем сложность алгоритма $O(n*log_2 n)$
=== Алгоритм восстановления ===
Для восстановления таблицы перестановки из таблицы инверсий(не умаляя общности длина таблицы равна n) создаем таблицу, которую будем расширять, по мере добавления в неё чисел, добавляем . Добавляем в эту таблицу число i (где i от n до 1) на позицию k+1, где k - число в таблице инверсий на i-том месте. Данный алгоритм довольно прост в реализации, но без использования дополнительных структур данных, имеет сложность $O(n^2)$, т. к. для вставки элемента в определённую позицию, требуется порядка $n$ перестановок элементов.
{|width="150" align="right" cellpadding="5" border="1" style="border-collapse: collapse;"|-| <span style="font-size:smaller;">Получение таблицы перестановки из таблицы инверсии</span> Приведём алгоритм восстановления с использованием [2 3 6 4 0 2 2 1 0] - т. инверсии [9] [9 8] [9 8 7] [9 8 6 7] [5 9 8 6 7Сортировка слиянием|сортировки слиянием] [5 9 8 6 4 7] [5 9 8 6 4 7 3] [5 9 8 2 6 4 7 3] [5 9 1 8 2 6 4 7 3] - т, имеющий сложность $O(n*log_2 n)$. перестановки|-}
Пусть $\alpha$ - цепочка упорядоченных пар целых неотрицательных чисел $[m_1, n_1]...[m_k, n_k]$. Рассмотрим двоичную операцию $o$, рекурсивно определенную на парах таких цепочек следующим образом: $([m, n]\alpha)o([m', n']\beta)=\left\{\begin{aligned}[] [m,n](\alpha o ([m'-m, n']\beta)), m \le m',\\ [m', n'](([m-m'-1, n]\alpha) o \beta), m>m'.\\ \end{|widthaligned} \right.$ Сопоставим каждому элементу таблицы инверсий его номер. Получится множество упорядоченных пар чисел $[m_1, n_1]...[m_k, n_k]$, где $m$ - сам элемент, а $n$ - его номер. Разобьем данные элементы на пары и произведём с ними операцию $o$. Получим некоторое количество цепочек упорядоченных пар. Также разбиваем их на пары и производим операцию $o$. Так действуем, пока не останется одна цепочка. Выписывая вторые элементы данных упорядоченных пар в том порядке, в каком они представлены в цепочке, получим первоначальную перестановку. ="150" align="right" cellpaddingПример ="5" border=" $[4, 1" style="border, 6, 3, 2, 2, 1, 1, 1, 0]$ -collapse: collapse;"таблица инверсий.|-| <span style="font-size:smaller;">Получение таблицы инверсии из таблицы перестановки</span> $[4,1]o[5 9 1 8 ,2 ], [6 ,3]o[3,4 ], [2,5]o[2,6], [1,7 3] - т. перестановки o[1,8], [1,9]o[ 0,10]$  $[ 1 0,2] [ 2 ,1 0] o[3,4][ 2 ,3], [2 ,5][0,6]o[1 ,7][0,8], [0,10][0,9]$  $[ 0 1,2 ][2 ,1 ][0,4] [ 4 0 2 2 ,3]o[1 ,7][0,5] [ 0,6 4 ][0,8], [0,10][0 ,9]$  $[1,2 2 ][0,7][0,5][0,1 ][0,4][0,6][0,8][0,3]o[0,10][0,9]$  $[0,10][ 3 6 4 0 ,2 2 ][0,7][0,5][0,1 ][0,4][0,6][0,8] [2 0,3 6 4 ][0 ,9]$  Получаем перестановку $[10, 2 2 , 7, 5, 1 0, 4, 6, 8, 3, 9] $ = Источники = Д. Кнут - тИскусство программирования, том 3. инверсии|-}
</wikitex>
64
правки

Навигация