Jak sloučit dva BST je efektivně?

hlasů
23

Jak sloučit dva binární vyhledávací stromy udržování majetku BST?

Pokud se rozhodneme, aby každý prvek ze stromu a vložit ji do druhého, složitost této metody by byly O(n1 * log(n2)), kde n1je počet uzlů stromu (řekněme T1), které jsme rozdělena, a n2je počet uzlů druhý strom (řekněme T2). Po této operaci jediný BST má n1 + n2uzly.

Moje otázka zní: můžeme dělat lépe než O (n1 * log (N2))?

Položena 17/06/2009 v 18:35
zdroj uživatelem
V jiných jazycích...                            


6 odpovědí

hlasů
8

A co sloučení obou stromů do tříděných seznamů, sloučení seznamy a pak vytvoří nový strom?

Odpovězeno 17/06/2009 v 18:43
zdroj uživatelem

hlasů
18
  • Zploštit stromy do tříděných seznamů.
  • Sloučení tříděných seznamů.
  • Vytvořte strom ze sloučeného seznamu.

IIRC, že je O (n1 + n2).

Odpovězeno 17/06/2009 v 18:43
zdroj uživatelem

hlasů
26

Naaff odpověď s trochu více detailů:

  • Sloučení BST do seřazený seznam je O (N)
    • Je to prostě „in-order“ iterace na celém stromě.
    • Dělá to na obou je O (n1 + n2)
  • Sloučení dvou setříděné seznamy je do jednoho seřazené seznamu je O (n1 + n2).
    • Udržovat ukazatele na hlavách obou seznamech
    • Vyberte menší hlavu a pokročit v jeho ukazatel
    • To je, jak sloučení merge-sort děl
  • Vytvoření dokonale vyvážené BST z tříděného seznamu je O (N)
    • Hodnota ve středu by kořen, a recurse.
    • V našem případě je seřazený seznam je velikosti n1 + n2. tak O (n1 + n2)
    • Výsledný strom bude koncepční BST binárního vyhledávání v seznamu

Tři kroky O (n1 + n2) vést k O (n1 + n2)

Pro N1 a N2 stejného řádu, je to lepší než O (n1 * log (n 2))

Odpovězeno 18/06/2009 v 01:14
zdroj uživatelem

hlasů
1

Jonathan

Po vytřídění, máme seznam délky n1 + n2. Budování binární strom z toho bude mít log (n1 + n2) čas. To je stejné jako slučovací druhu, jen to, že při každém kroku rekurzivní zvyklý mít O (n1 + n2) termín, jak jsme v slučovací druhu algoritmu. Takže složitost doba je log (n1 + n2).

Právě složitost celého problému je O (n1 + n2).

Také bych řekl, tento přístup je dobré, pokud dva seznamy jsou srovnatelné velikosti. V případě, že rozměry nejsou srovnatelné, pak je nejlepší vložit každý uzel malý strom do velkého stromu. To bude trvat O (n1 * log (n2)) čas. Například pokud máme dva stromy jeden velikosti 10 a další velikosti 1024. Zde n1 + n2 = 1034, kde jako n1log (N2) = 10 * 10 = 100. Takže přístup záviset na velikosti obou stromů.

Odpovězeno 27/07/2010 v 22:08
zdroj uživatelem

hlasů
0

O (n1 * log (n2)) je průměrný scénář, i když máme 2 sloučení jakýkoliv netříděného seznamu na BST. Nejsme s využitím k tomu, že seznam je seřazen seznam nebo BST.

Podle mě Předpokládejme, jednu BST má n1 prvky a druhý má n2 prvků. Nyní převést jeden BST do tříděného Array Seznam L1 v O (N1).

Sloučený BST (BST, Array)

if (Array.size == 0) vratné BST, pokud (Array.size == 1) vložit prvek v BST. vrátit BST;

Vyhledá index do pole, jehož levá element <BST.rootnode a pravý element> = BST.rootnode říkat index. if (BST.rootNode.leftNode == null) // bez levé uzel {zasunout pole z indexu na 0 do levé BST a} jinak {Sloučen BST (BST.leftNode, Array {0 až Index})}

if (BST.rootNode.rightNode == null) // tj č přímo uzel {zasunout pole z indexu na Array.size do pravé BST} jinak {Sloučen BST (BST.rightNode, Array {Rejstřík Array.size} )}

vrátit BST.

Tento algoritmus bude trvat << času než O (n1 * log (N2)) jako pokaždé, když jsme se rozdělením pole a BST zvládnout podproblém.


Odpovězeno 30/08/2010 v 11:12
zdroj uživatelem

hlasů
-1

Myšlenka je použít iterativní inorder průchod. Používáme dvě pomocné zásobníky na dva BSTs. Vzhledem k tomu musíme tisknout prvky v utříděné podobě, kdykoli dostaneme menší prvek z některého z stromů, my ji vytisknout. V případě, že element je větší, pak se přesuneme zpět do fronty pro další iteraci.

Odpovězeno 08/01/2013 v 07:04
zdroj uživatelem

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