Если вы хотите посчитать количество перестановок, необходимое для сортировки вставок, то вы хотите найти следующее число: для каждого элемента, сколько предыдущих элементов в массиве меньше его?Сумма этих значений равна общему количеству выполненных обменов.
Чтобы найти число, вы можете использовать дерево статистики заказов, сбалансированное двоичное дерево поиска, которое может эффективно подсказать, сколько элементов в деревеменьше, чем некоторый данный элемент.В частности, дерево статистики orde поддерживает O (log n) вставку, удаление, поиск и подсчет того, сколько элементов в дереве меньше некоторого значения.Затем вы можете подсчитать, сколько свопов будет выполнено, следующим образом:
- Инициализировать новое пустое дерево статистики заказов.
- Установить счетчик = 0
- Для каждого массиваэлемент в порядке:
- Добавьте элемент в дерево статистики заказов.
- Добавьте, чтобы подсчитать количество элементов в дереве меньше добавленной стоимости.
- Возвращаемое количество,
Это делает O (n) итераций цикла, который занимает O (log n) времени, поэтому общая выполненная работа составляет O (n log n), чтобыстрее, чем метод грубой силы.
Если вы хотите посчитать количество перестановок в сортировке выбора, то вы можете использовать тот факт, что сортировка вставкой будет выполнять своп только на k-м проходе, если,после обработки первых k-1 элементов списка элемент в позиции k не является k-м наименьшим элементом.Если вы можете сделать это эффективно, то у нас есть следующий базовый набросок алгоритма:
- Установить итог = 0
- Для k = 1 до n:
- Если элемент с индексом k не является k-м наибольшим элементом:
- Поменяйте его местами с k-м наибольшим элементом.
- Всего увеличения
- Возврат итого
Так, как мы реализуем это эффективно?Нам необходимо эффективно проверять, является ли элемент в данном индексе правильным элементом, а также эффективно находить позицию элемента, которая действительно принадлежит данному индексу.Для этого начните с создания сбалансированного бинарного дерева поиска, которое отображает каждый элемент на его позицию в исходном массиве.Это занимает время O (n log n).Теперь, когда у вас есть сбалансированное дерево, мы можем расширить структуру, назначив каждому элементу дерева позицию в отсортированной последовательности, которой принадлежит этот элемент.Один из способов сделать это - использовать дерево статистики заказов, а другой - перебирать дерево с помощью обхода по порядку, аннотируя каждое значение в дереве своей позицией.
Используя эту структуру, мы можем проверитьO (log n) время, когда элемент находится в правильном положении, просматривая элемент в дереве (время O (log n)), затем просматривая положение в отсортированной последовательности, в котором он должен быть, и в которомположение, в котором он находится в данный момент (помните, что мы установили это при создании дерева).Если он не согласен с нашей ожидаемой позицией, то он находится не в том месте, в противном случае он находится в правильном месте.Кроме того, мы можем эффективно смоделировать обмен двух элементов, посмотрев эти два элемента в дереве (O (log n) общего времени), а затем поменяв их местами в O (1).
В результатемы можем реализовать вышеупомянутый алгоритм за время O (n log n) - O (n log n) времени, чтобы построить дерево, затем n итераций выполнения O (log n) работы, чтобы определить, следует ли поменяться местами.
Надеюсь, это поможет!