Дан двусвязный список, в котором элементы данных отсортированы в порядке возрастания. Создайте сбалансированное бинарное дерево поиска, в котором есть те же элементы данных, что и в двусвязном списке. Дерево должно быть построено на месте (новый узел не должен быть выделен для преобразования дерева)
Примеры:
Input: Doubly Linked List 1 2 3 Output: A Balanced BST 2 / \ 1 3 Input: Doubly Linked List 1 2 3 4 5 6 7 Output: A Balanced BST 4 / \ 2 6 / \ / \ 1 3 4 7 Input: Doubly Linked List 1 2 3 4 Output: A Balanced BST 3 / \ 2 4 / 1 Input: Doubly Linked List 1 2 3 4 5 6 Output: A Balanced BST 4 / \ 2 6 / \ / 1 3 5
Преобразование «Двойной связанный список» очень похоже на проблему «Единый связанный список», и метод 1 точно такой же, как метод 1 из предыдущего поста . Способ 2 тоже почти такой же. Единственное отличие в методе 2 состоит в том, что вместо выделения новых узлов для BST мы повторно используем одни и те же узлы DLL. Мы используем указатель prev как левый, а следующий указатель как правый.
Способ 1 (простой)
Ниже приведен простой алгоритм, в котором мы сначала находим средний узел списка и делаем его корнем дерева, которое будет построено.
1) Get the Middle of the linked list and make it root. 2) Recursively do same for left half and right half. a) Get the middle of left half and make it left child of the root created in step 1. b) Get the middle of right half and make it right child of the root created in step 1.
Временная сложность: O (nLogn), где n — количество узлов в связанном списке.
Метод 2 (хитрый)
Метод 1 строит дерево от корня до листьев. В этом методе мы строим от листьев до корня. Идея состоит в том, чтобы вставлять узлы в BST в том же порядке, что и в двусвязном списке, так что дерево может быть построено за O (n) временной сложности. Сначала мы посчитаем количество узлов в данном связанном списке. Пусть счет будет n. После подсчета узлов мы берем n / 2 левых узлов и рекурсивно создаем левое поддерево. После создания левого поддерева мы назначаем средний узел корневому узлу и связываем левое поддерево с корневым. Наконец, мы рекурсивно создаем правильное поддерево и связываем его с корнем.
При создании BST мы также продолжаем перемещать указатель заголовка списка на следующий, чтобы у нас был соответствующий указатель в каждом рекурсивном вызове.
Ниже приведена реализация метода 2. Основной код, который создает сбалансированный BST, выделен.
|
С
|
Джава
|
Выход:
Given Linked List 1 2 3 4 5 6 7 Pre-Order Traversal of constructed BST 4 2 1 3 6 5 7
Сложность времени: O (n)
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
Рекомендуемые посты:
- Сортированный связанный список с сбалансированным BST
- Merge K отсортировал двусвязный список в отсортированном порядке
- Сортированное объединение двух отсортированных дважды круговых связанных списков
- Вставить значение отсортированным способом в отсортированный двусвязный список
- С учетом связного списка, который отсортирован, как вы будете вставлять в отсортированном виде
- Объединение двух сбалансированных бинарных поисковых деревьев
- Найти сбалансированный узел в связанном списке
- Объединить два отсортированных списка (на месте)
- Пересечение двух отсортированных связанных списков
- Объединить два отсортированных связанных списка
- Merge K отсортированные связанные списки | Комплект 1
- Проверьте, является ли связанный список попарно отсортирован
- Поиск медианы в отсортированном связанном списке
- Сортировать ак отсортированный двусвязный список
- Объединить K отсортированных связанных списков | Набор 2 (с использованием Min Heap)
0.00 (0%) 0 votes