Как эффективно объединить два BST-х?

голоса
23

Как объединить два бинарных деревьев поиска, сохранив свойство BST?

Если мы решили взять каждый элемент из дерева и вставить его в другой, сложность этого метода была бы O(n1 * log(n2)), где n1это число узлов дерева (скажем T1), которые мы расщепленных и n2это число узлов другое дерево (скажем T2). После этой операции только один БСТ имеет n1 + n2узлы.

Мой вопрос: можем ли мы сделать лучше, чем O (n1 * журнал (n2))?

Задан 17/06/2009 в 18:35
источник пользователем
На других языках...                            


6 ответов

голоса
8

Как насчет уплощения оба дерев в отсортированные списки, слияние списков, а затем создать новое дерево?

Ответил 17/06/2009 в 18:43
источник пользователем

голоса
18
  • Свести дерева в отсортированные списки.
  • Слияние отсортированных списков.
  • Создать дерево из объединенного списка.

IIRC, то есть O (n1 + n2).

Ответил 17/06/2009 в 18:43
источник пользователем

голоса
26

Ответ Naaff с немного более подробно:

  • Выпрямления BST в отсортированный список является O (N)
    • Это просто «в заказе» итерация по всему дереву.
    • Делать это для обоих O (n1 + n2)
  • Объединение двух отсортированных списков в один отсортированный список является O (n1 + n2).
    • Держите указатели глав обоих списков
    • Выберите меньшую голову и продвигать свой указатель
    • Это как слияние слияния-сортировка работ
  • Создание идеально сбалансированный BST из отсортированного списка O (N)
    • Значение в середине будет корень, и рекурсия.
    • В нашем случае упорядоченный список имеет размер n1 + n2. так O (n1 + n2)
    • В результате дерево будет концептуальное BST двоичного поиска список

Три шага O (n1 + n2) в результате O (n1 + n2)

Для n1 и n2 того же порядка, что лучше, чем O (n1 * журнал (n2))

Ответил 18/06/2009 в 01:14
источник пользователем

голоса
1

Джонатан,

После сортировки, у нас есть список длина n1 + n2. Построение бинарного дерева из него будет взять журнал (n1 + n2). Это же, как и сортировки слиянием, только то, что на каждом шаге рекурсии мы не будем иметь O (n1 + n2) член, как у нас в алгоритме сортировки слиянием. Таким образом, время сложность журнала (n1 + n2).

Теперь сложность всей задачи O (n1 + n2).

Кроме того, я бы сказал, такой подход хорош, если два списка сопоставимого размера. Если размеры не сопоставимы, то лучше всего, чтобы вставить каждый узел небольшого дерева в большое дерево. Это займет O (n1 * журнала (n2)) время. Например, если мы имеем два дерева одного размера 10, а другой размер 1024. Здесь n1 + n2 = 1 034, где в качестве n1log (n2) = 10 * 10 = 100. Таким образом, подход должен зависеть от размеров двух деревьев.

Ответил 27/07/2010 в 22:08
источник пользователем

голоса
0

O (n1 * журнал (n2)) представляет собой средний сценарий, даже если мы имеем 2 слияния любой несортированный список в BST. Мы не используя тот факт, что список отсортирован список или BST.

По мне Давайте предположим, один BST имеет n1 элементов и других имеет n2 элементов. Теперь преобразовать один BST в отсортированный массив Список L1 в O (n1).

Объединенное BST (BST, Array)

если (Array.size == 0) возвращение БСТ, если (Array.size == 1) вставить элемент в BST. вернуться BST;

Найти индекс в массиве, левая элемент <BST.rootnode и правый элемент> = BST.rootnode сказать индекс. если (BST.rootNode.leftNode == NULL) // т.е. нет левого узла {вставьте все массивы из индекса 0, в левую BST и} еще {Объединенное BST (BST.leftNode, массив {0} Индекс)}

если (BST.rootNode.rightNode == NULL) // т.е. нет правого узла {вставить все массивы из индекса в Array.size в правом BST} еще {Объединенное BST (BST.rightNode, массив {Указатель Array.size} )}

вернуться BST.

Этот алгоритм будет принимать << время, чем O (n1 * журнал (n2)), как каждый раз, когда мы разметка массива и BST для обработки подзадачи.


Ответил 30/08/2010 в 11:12
источник пользователем

голоса
-1

Идея заключается в том, чтобы использовать итеративные симметричный обход. Мы используем два вспомогательных стеки для двух BSTs. Так как нам нужно напечатать элементы в отсортированном виде, когда мы получаем меньший элемент из любого из деревьев, мы выводим его. Если элемент больше, то мы помещаем его обратно в стек для следующей итерации.

Ответил 08/01/2013 в 07:04
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more