Egy adott bináris fa, maximális bináris keresés sub-tree

szavazat
13

Egy adott bináris fa található a legnagyobb részfájának ami szintén bináris keresési fa?

Példa:

Bemenet:

                   10
               /         \
             50           150
            /  \         /   \
          25    75     200    20
         / \   / \    /  \    / \
        15 35 65 30  120 135 155 250 

output:

                   50
                  /   \
                 25   75
                / \   /
               15 35  65
A kérdést 02/07/2010 06:15
a forrás felhasználó
Más nyelveken...                            


7 válasz

szavazat
0

A bináris keresési fa kapsz egy rendezett eredmény, ha egy IN-ORDER bejárás. Szóval, egy in-order bejárás a teljes bináris fa. A leghosszabb rendezve szekvencia a legnagyobb bináris keresés al fa.

  • Van egy inorder bejárása elemek (LÁTOGATÁS BAL, keresse ROOT, keresse JOBB)
  • Eközben kap a csomópont adatokat, hasonlítsa össze, hogy az előző csomópont adatok kisebb, mint a következő adatokat. Ha igen, növeljük számláló 1. Store start csomópontot.
  • Amikor az összehasonlítás sikertelen, tárolja a végső csomópont és nullázza a számlálót 0
  • Tárolja az adatokat (számláló, kezdete, vége) csomópontot tömbszerkezetű később megtalálják amely miután a maximális érték, és hogy megadja a leghosszabb bináris keresés al-fa
Válaszolt 02/07/2010 06:26
a forrás felhasználó

szavazat
2

Érdekes kérdés!

Saját korábbi kísérlet volt moronically rossz!

Itt van egy újabb kísérlet (remélhetőleg helyes ez idő szerint).

Én feltételezve, hogy a fa csatlakozik.

Tegyük fel, hogy minden egyes csomóponthoz n a fa, akkor volt egy sor leszármazottai n, S n a tulajdonság, hogy

  • Minden egyes tagja x S n , az egyedi útvonal n x bináris kereső fába (ez csak egy út, de akkor is úgy, hogy egy fa).

  • Minden leszármazottja y x, úgy, hogy az út a n y egy BST, y S n .

A csomópontok halmaza S n , megadja a legnagyobb BST gyökerű n.

Mi lehet építeni S n minden egyes csomóponthoz csinál egy mélységi keresés a fán, és halad az útvonal adatait (az út a gyökér a jelenlegi csomópont), és frissíti a készlet a csomópontok az útvonal által visszalépés az ösvényen.

Amikor elmegyünk egy csomópont, sétálunk fel az utat, és ellenőrizze, hogy a BST tulajdonság teljesül szegmens számára az utat lépett eddig. Ha igen, akkor adjuk hozzá a jelenlegi csomópont a megfelelő sor a csomópont az út már csak sétált. Abbahagyjuk ösvényén a pillanatban a BST ingatlan megsértik. Ellenőrzése, ha a pályaszakasz sétáltunk eddig egy BST lehet tenni O (1) idő, egy O (PATH_LENGTH) idő a teljes feldolgozási idő, minden egyes csomóponthoz.

A végén, minden egyes csomópont lesz a megfelelő S n lakott. Mi lehet járni a fa most, és vedd a csomópont a legnagyobb értéke S n .

Az az idő, mert ez az összeg mélyben a csomópontok (a legrosszabb esetben), és ez O (nlogn) átlagos esetben (lásd 5.2.4 http://www.toves.org/books/ adatok / ch05-fák / index.html ), de O (n ^ 2) a legrosszabb esetben.

Talán okosabb módon, hogy frissítse a készlet garantálja csökken a legrosszabb esetben időben.

A pszeudo-kód lehet valami hasonló:

static Tree void LargestBST(Tree t)
{
    LargestBST(t, new List<Pair>());
    // Walk the tree and return the largest subtree with max |S_n|.
}

static Tree LargestBST(Tree t, List<Pair> path)
{
    if (t == null) return;

    t.Set.Add(t.Value);

    int value = t.Value;
    int maxVal = value;
    int minVal = value;

    foreach (Pair p in path)
    {
        if (p.isRight)
        {
            if (minVal < p.node.Value)
            {
                break;
            }
        }

        if (!p.isRight)
        {
            if (maxVal > p.node.Value)
            {
                break;
            }
        }

        p.node.Set.Add(t.Value);

        if (p.node.Value <= minVal)
        {
            minVal = p.node.Value;
        }

        if (p.node.Value >= maxVal)
        {
            maxVal = p.node.Value;
        }
    }

    Pair pl = new Pair();
    pl.node = t;
    pl.isRight = false;

    path.Insert(0, pl);
    LargestBST(t.Left, path);

    path.RemoveAt(0);

    Pair pr = new Pair();
    pr.node = t;
    pr.isRight = true;

    path.Insert(0, pr);

    LargestBST(t.Right, path);

    path.RemoveAt(0);

}
Válaszolt 02/07/2010 14:13
a forrás felhasználó

szavazat
0
GetLargestSortedBinarySubtree(thisNode, ref OverallBestTree)
    if thisNode == null
        Return null
    LeftLargest = GetLargestSortedBinarySubtree(thisNode.LeftNode, ref OverallBestTree)
    RightLargest = GetLargestSortedBinarySubtree(thisNode.RightNode, ref OverallBestTree)
    if LeftLargest.Max < thisNode.Value & RightLargest.Min > thisNode.Value
        currentBestTree = new BinaryTree(LeftLargest, thisNode.Value, RightLargest)
    else if LeftLargest.Max < thisNode.Value
        currentBestTree = new BinaryTree(LeftLargest, thisNode.Value, null)
    else if RightLargest.Min > thisNode.Value
        currentBestTree = new BinaryTree(null, thisNode.Value, RightLargest)
    else
        currentBestTree = new BinaryTree(null, thisNode.Value, null)
    if (currentBestTree.Size > OverallBestTree.Size)
        OverallBestTree = currentBestTree
    return currentBestTree

Amint BlueRaja rámutatott, ez az algoritmus nem megfelelő.

Meg kell igazán nevezhető GetLargestSortedBinarySubtreeThatCanBeRecursivelyConstructedFromMaximalSortedSubtrees.

Válaszolt 02/07/2010 19:46
a forrás felhasználó

szavazat
3

Az előző algoritmus (lásd változathoz) volt O(n^2)- tudjuk általánosítani, hogy O(n log n)az észre, hogy a tények:

  1. Ha b a gyökere a legnagyobb BST és b.left.value < b.value, akkor b.leftis a BST (azonos b.right.value ≥ b.value)
  2. Ha b a gyökere a legnagyobb BST és szintén a BST, akkor minden csomópont között a és b a BST.

Tehát, ha c és b között, és c nem a BST gyökerezik által b, sem a (miatt (2.)) . Ezzel Sőt, mi könnyen megállapíthatjuk, hogy a csomópont a BST gyökerezik által adott őse. Majd ezt átadásával egy csomópontot a funkció együtt listája ősök, és a hozzá tartozó min / maxValues, hogy a jelenlegi gyermek-csomópont volna kielégíteni, ha valóban olyan őse volt a gyökere a legnagyobb BST (mi” ll hívja ezt a listát ancestorList). A rendszer tárolja a teljes gyűjtemény potenciál gyökereioverallRootsList

Nézzük meg egy szerkezet az úgynevezett potentialRoot az alábbiak szerint:

Minden potentialRoot tartalmazza a következő értékeket:
* csomópont : A csomópont gondolkodunk a gyökér a BST
* MINVALUE és MAXVALUE : a tartomány egy másik csomópont közé kell esnie, hogy része legyen a BST gyökerezik a csomópont (különböző minden node)
* subNodes : a listát a többi csomópont a legnagyobb BST gyökerezik a csomópont

A pszeudo-kód így néz ki (megjegyezzük, hogy az összes említett listákról listái potentialRoots) :

FindLargestBST(node, ancestorList):
    leftList, rightList = empty lists
    for each potentialRoot in ancestorList:
        if potentialRoot.minValue < node.Value ≤ potentialRoot.maxValue:
            add node to potentialRoot.subNodes (due to (1.))
            (note that the following copies contain references, not copies, of subNodes)
            add copy of potentialRoot to leftList, setting maxValue = node.Value
            add copy of potentialRoot to rightList, setting minValue = node.Value

    add the potentialRoot (node, -∞, +∞) to leftList, rightList, and overallRootsList
    FindLargestBST(node.left, leftList)
    FindLargestBST(node.right, rightList)

A végén overallRootsListlesz egy lista npotentialRoots, mindegyik egy listát a subNodes. Az egyik legnagyobb subNodes lista a BST.

Mivel <treeHeight értékeket ancestorList, akkor (feltételezve, hogy a fa kiegyensúlyozott), az algoritmus futO(n log n)

Válaszolt 02/07/2010 20:21
a forrás felhasználó

szavazat
0
root(Tree L A R) = A

MaxBST(NULL) = (true, 0, NULL)
MaxBST(Tree L A R as T) = 
  let
    # Look at both children
    (L_is_BST, L_size, L_sub) = MaxBST(L)
    (R_is_BST, R_size, R_sub) = MaxBST(R)
  in
  # If they're both good, then this node might be good too
  if L_is_BST and R_is_BST and (L == NULL or root(L) < A) and (R == NULL or A < root(R))
  then (true, 1 + L_size + R_size, T)
  else
       # This node is no good, so give back the best our children had to offer
       (false, max(L_size, R_size), if L_size > R_size then L_sub else R_sub)

Úgy néz ki, minden egyes csomópontja pontosan egyszer, így fut O (N).

Edit: Crud, ez nem tartja hagyhat ki egyes részein részfa. Amikor olvastam részfa, feltételeztem „az egész fát gyökerű néhány node”. Menjek vissza, hogy erősít ez később.

Válaszolt 03/07/2010 01:15
a forrás felhasználó

szavazat
4

Ez a válasz korábban tartalmazott egy O (n log n) alapuló algoritmust linket / kivágott fák. Itt van egy egyszerűbb O (n) oldat.

A mag egy eljárás, amely elfogadja a csomópont, az egyedi maximális BSST gyökerű bal fia, az egyedülálló maximum BSST gyökerű jobb fia, és rámutatnak a bal szélső és jobb szélső eleme ezeknek BSSTs. Ez tönkreteszi bemeneteinek (elkerülhető perzisztáló adatstruktúrákat) és felépíti az egyedülálló maximális BSST gyökerezik az adott csomóponthoz, együtt a minimum és maximum elemek. Minden BSST csomópontok jegyzetekkel számával leszármazottai. Mint korábban, ez az eljárás az úgynevezett ismételten utáni sorrendben bejárás. Ahhoz, hogy visszaszerezze az al-fa, emlékszik a gyökér a legnagyobb BSST; rekonstruálva igényel csak egy egyszerű bejárás.

Majd kezelni a bal BSST csak; a megfelelő szimmetrikus. Ha a gyökér a bal BSST nagyobb, mint az új gyökér, akkor az egész al-fa eltávolítjuk, és az új gyökér most legbaloldalibb. Egyébként a régi bal szélső csomópont továbbra legbaloldalibb. Kezdve a jobb szélső csomópont a bal BSST és felfelé mozog, megtalálja az első csomópont, amely kisebb vagy egyenlő, mint a gyökér. Jobb fia meg kell szüntetni; figyelmét most, hogy mivel a BST tulajdon, nincs más csomópontokat kell menni! Folytassuk a gyökér a bal BSST, frissíti a számít, hogy az tükrözze a törlést.

Az ok ez O (n) az, hogy annak ellenére, a hurok, minden éle az eredeti fa lényegében áthaladni csak egyszer.


EDIT: együttesen a pályák áthaladni a maximális egyenes utak a BST, kivéve a bal gerinc és a megfelelő gerinc. Például a bemeneti

              H
             / \
            /   \
           /     \
          /       \
         /         \
        /           \
       /             \
      D               L
     / \             / \
    /   \           /   \
   /     \         /     \
  B       F       J       N
 / \     / \     / \     / \
A   C   E   G   I   K   M   O

Itt vannak a rekurzív hívások, amelyen minden élét áthaladni:

              H
             / \
            /   \
           /     \
          /       \
         /         \
        /           \
       /             \
      D               L
     / h             h \
    /   h           h   \
   /     h         h     \
  B       F       J       N
 / d     d h     h l     l \
A   C   E   G   I   K   M   O
Válaszolt 03/07/2010 17:46
a forrás felhasználó

szavazat
1

LEGNAGYOBB bináris keresés fa egy bináris fa:

Kétféleképpen tudjuk megközelíteni ezt a problémát,

i) A legnagyobb BST nem indukált (ebből egy csomópont, minden gyermek nem kell kielégíteni a BST feltétel)

ii) A legnagyobb BST indukált (ebből egy csomópont, minden gyermek kielégíti a BST feltétel)

Megbeszéljük a legnagyobb BST (nem indukálja) itt. Követjük alulról felfelé irányuló megközelítés (Post érdekében bejárás), hogy megoldja ezt.

a) Reach a levél csomópont

b) Egy csomópontja (a levél) visszatér egy TreeNodeHelper tárgy, amely az alábbi mezőket benne.

public static class TreeNodeHelper {
        TreeNode node;
        int nodes;
        Integer maxValue;
        Integer minValue;
        boolean isBST;


        public TreeNodeHelper() {}

        public TreeNodeHelper(TreeNode node, int nodes, Integer maxValue, Integer minValue, boolean isBST) {
            this.node = node;
            this.nodes = nodes;
            this.maxValue = maxValue;
            this.minValue = minValue;
            this.isBST = isBST;
        }      
    }

c) Kezdetben a levél csomópont, csomópontok = 1, isBST = true, MINVALUE = MAXVALUE = node.data. És tovább, a csomópontok száma növekedni fog, ha eleget tesz a BST állapotban.

d) Segítségével ezt ellenőrizni fogjuk a BST állapot aktuális csomópont. És mi lesz megismételni ugyanazt évig gyökér.

e) minden egyes csomópont két tárgy kerül vissza. az egyik utolsó maximum BST és egy másik aktuális BST kielégítő csomópontokat. Tehát minden egyes csomópont (fent levél) (2 + 2) = 4 (2 a bal részfa és 2 jobb al-fa) tárgyak összehasonlítását és két küldjük vissza.

f) A végső legnagyobb csomópont objektumot gyökér lesz a legnagyobb BST

PROBLÉMA:

Van egy probléma ezzel a megközelítéssel. Bár ezt követően a megközelítés, ha a részfa nem felel meg a BST állapotban az aktuális csomópont, nem tudjuk egyszerűen figyelmen kívül hagyja a részfa (még akkor kevesebb számú csomópont). Például

 55
  \
   75
  /  \
 27  89
    /  \
   26  95
      /  \
     23  105
         /  \
        20  110

A levél csomópontok (20.110) a tárgyak vizsgálandó csomóponthoz (105), ez megfelel annak a feltételnek. De amikor eléri csomópont (95) a levél csomópont (20) nem felel meg a BST állapotban. Mivel ez a megoldás a BST (nem indukálódik) nem szabad figyelmen kívül hagyni csomópont (105) és a csomópont (110), amely kielégíti azt az állapotot. Tehát csomópont (95) van, hogy visszalép újra teszteli BST állapot és a fogást azokat a csomópontokat (105, 110).

A teljes kód végrehajtását elérhető ezen a linken

https://github.com/dineshappavoo/Implementation/tree/master/LARGEST_BST_IN_BT_NOT_INDUCED_VER1.0

Válaszolt 27/03/2014 00:48
a forrás felhasználó

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