Этот вопрос похож на Сортированный список для завершения представления массива BST , но, возможно, более конкретно.Этот вопрос может быть использован для решения динамической вставки узла в полное двоичное дерево поиска .
Рассмотрим полное двоичное дерево , представленное в памяти как непрерывный массив a[0..n)
,где элемент a[0]
является корнем дерева, а для любого узла a[i]
у него есть левый дочерний элемент a[2*i+1]
и правый дочерний элемент a[2*i+2]
(если эти индексы меньше n
).
Программисты C ++ будут знакомы с этим представлением, потому что оно используется std::make_heap
.std::make_heap(a, a+n)
принимает несортированный массив (который можно рассматривать как несортированное полное двоичное дерево) и переставляет его элементы (которые можно рассматривать как повороты дерева), чтобы превратить дерево в полный двоичный файл куча , где каждый узелзначение больше, чем любой из его детей.Мы говорим, что результирующий массив находится в «максимальном порядке кучи».
С другой стороны, если значение каждого узла больше, чем его левый потомок, но меньше, чем его правый потомок, то мы говорим, что полный двоичный файлдерево представляет собой полный двоичный файл дерево поиска .В этом случае предположим, что результирующий массив находится в «порядке уровней». [1]
В то время как существует множество допустимых «порядков максимальной кучи» для данного набора элементов, каждыйнабор элементов имеет только один уникальный «порядок уровней».
Следующие векторы расположены в порядке уровней:
std::vector<int> v1 = { 3, 1, 4, 0, 2 };
// corresponds to the complete binary search tree
// 3
// 1 4
// 0 2
std::vector<int> v2 = { 6, 3, 8, 1, 5, 7, 9, 0, 2, 4 };
// corresponds to the complete binary search tree
// 6
// 3 8
// 1 5 7 9
// 0 2 4
Я ищу семейство эффективных алгоритмов для:
- перестановка несортированной последовательности в порядок уровней
- перестановка отсортированной последовательности в порядок уровней
- перестановка последовательности порядка уровней в отсортированный порядок
Когда я говорю эффективный , я имею в виду алгоритмы, которые работают без глубокой рекурсии, без динамического выделения памяти и без временных массивов.Я уже знаю, что перестановка не может быть сделана особенно быстро;Я бы надеялся на O (n lg n).
Обратите внимание, что части 2 и 3 в основном просят придумать отображение OldIndex -> NewIndex
;как только у вас есть такая функция, вы можете выполнить перестановку на месте, используя один из этих алгоритмов .
Часть 1 запрашивает реализацию nonstd::make_searchtree
по аналогии с std::make_heap
.Часть 3 требует реализации nonstd::sort_searchtree
по аналогии с std::sort_heap
.
[1] - я в основном придумал этот термин «порядок уровней».Если вы знаете более широко признанный академический термин для этого заказа, пожалуйста, оставьте комментарий!