Voor een gegeven binaire boom vinden maximale binary search sub-boom

stemmen
13

Voor een gegeven binaire boom, op zoek naar de grootste sub-boom die ook binaire zoekboom?

Voorbeeld:

Invoer:

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

Output:

                   50
                  /   \
                 25   75
                / \   /
               15 35  65
De vraag is gesteld op 02/07/2010 om 06:15
bron van user
In andere talen...                            


7 antwoorden

stemmen
0

Een binaire zoekboom zal u een gesorteerde resultaat geven als je een IN-ORDER Traversal. Dus, doe een in-orde traversal voor de gehele binaire boom. De langste gesorteerde volgorde is uw grootste binary search sub boom.

  • Doe een inorder traversal van elementen (VISIT LEFT, BEZOEK ROOT, BEZOEK RECHTS)
  • Terwijl u dit doet, krijgt het knooppunt gegevens vergelijken of de vorige knooppunt data kleiner te zijn dan de volgende data. Als dat zo is, verhogen de teller op 1. Sla de start node.
  • Als de vergelijking niet lukt, bewaar de eindknooppunt en reset de teller op 0
  • Bewaar deze informatie (teller, start, einde) knooppunt in een matrix structuur om later te vinden die met de maximale waarde en dat zal u de langste binary search sub boom geven
antwoordde op 02/07/2010 om 06:26
bron van user

stemmen
2

Interessante vraag!

Mijn eerdere poging was moronically verkeerd!

Hier is nog een poging (hopelijk corrigeren deze tijd).

Ik ga ervan uit de boom is aangesloten.

Stel dat voor elk knooppunt n van de boom, had je een set van afstammelingen van n, S n met de eigenschap dat

  • Voor elk lid x van S n , de unieke pad van n naar x een Binary Search Boom (het is slechts een pad, maar je kunt nog steeds beschouw het als een boom).

  • Voor elke nakomeling y of x, zodat het pad van n tot y een BST, y in S n .

De set van knooppunten S n , geeft u de grootste BST geworteld in n.

We kunnen S construeren n voor elk knooppunt door het doen van een depth-first search op de boom en passeren in de weginformatie (het pad van wortel tot het huidige knooppunt) en het bijwerken van de sets van de knopen in het pad terugwaarts langs het pad.

Als we een bezoek aan een knooppunt, lopen we het pad, en controleer of het onroerend goed BST is voldaan voor dat segment van het pad liep tot nu toe. Als dat zo is, voegen we het huidige knooppunt naar de ingestelde van het knooppunt van het pad dat we liepen gewoon aan. We stoppen met het lopen van de weg het moment dat de woning BST wordt geschonden. Controleer de baansegment we tot nu toe liepen een BST kan op O (1) tijd, een O (PATH_LENGTH) periode totale verwerkingstijd voor elk knooppunt.

Aan het eind zal elke node een overeenkomstige S n bevolkt. We kunnen de boom nu lopen en kies het knooppunt met de grootste waarde van S n .

De tijd die hiervoor is de som van de diepten van de knooppunten (in het ergste geval), en dat is O (nlogn) in het gemiddelde geval (zie paragraaf 5.2.4 van http://www.toves.org/books/ data / CH05-bomen / index.html ), maar O (n ^ 2) in het ergste geval.

Misschien is een slimmer manier om de sets te werken zal zorgen voor een vermindering in het ergste geval de tijd.

De pseudo-code kan iets als:

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);

}
antwoordde op 02/07/2010 om 14:13
bron van user

stemmen
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

Zoals BlueRaja opgemerkt, dit algoritme is niet correct.

Het moet echt worden genoemd GetLargestSortedBinarySubtreeThatCanBeRecursivelyConstructedFromMaximalSortedSubtrees.

antwoordde op 02/07/2010 om 19:46
bron van user

stemmen
3

Het vorige algoritme (zie herzieningen) was O(n^2)- kunnen we generaliseren om O(n log n)door op te merken het feit dat:

  1. Als b is de wortel van de grootste BST en b.left.value < b.valuedan b.leftook in de BST (hetzelfde voor b.right.value ≥ b.value)
  2. Als b is de wortel van de grootste BST en is ook de BST, dan elk knooppunt tussen a en b in het BST.

Dus als c tussen a en b en c niet in de BST verankerd door b, evenmin als een (door (2)) . Gebruik van dit feit, kunnen we gemakkelijk bepalen of een knooppunt in het BST verankerd door een bepaalde voorouder. We zullen dit doen door het passeren van een knooppunt in onze functie samen met een overzicht van de voorouders en de bijbehorende min / maxValues dat de huidige kind-knooppunt zou moeten voldoen als het inderdaad dat de voorouders waren de wortel van de grootste BST (we' ll noemen deze lijst ancestorList). We zullen de gehele collectie van de potentiële-roots op te slaan inoverallRootsList

Laten we een structuur genaamd potentialRoot definiëren als volgt:

Elke potentialRoot bevat de volgende waarden:
* knooppunt : Het knooppunt overwegen we de wortel van de BST
* MINVALUE en MAXVALUE : tussen een knooppunt moet tussen vallen van de BST verankerd door node (verschillend voor elk knooppunt)
* subnodes : Een lijst van de rest van de knooppunten in het grootste BST geworteld door knooppunt

De pseudo-code ziet er als volgt uit (er rekening mee dat alle genoemde lijsten zijn van 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)

Aan het einde overallRootsListzal een lijst van zijn npotentialRoots, elk met een lijst van subnodes. Degene met de grootste lijst subnodes is uw BST.

Aangezien er <treeHeight waarden in ancestorList, dan (uitgaande van de boom gebalanceerd), het algoritme uitgevoerd inO(n log n)

antwoordde op 02/07/2010 om 20:21
bron van user

stemmen
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)

Kijkt naar elke boom knooppunt precies één keer, dus loopt in O (N).

Edit: Crud, dit is niet van mening dat het kan je bij sommige delen van een substructuur. Toen ik subtree las, veronderstelde ik "de hele boom geworteld op een bepaald knooppunt". Ik kan terug naar deze later op te lossen.

antwoordde op 03/07/2010 om 01:15
bron van user

stemmen
4

Dit antwoord bevatte eerder een O (n log n) algoritme op basis van link / gekapte bomen. Hier is een eenvoudiger O (n) oplossing.

De kern is een procedure die een knooppunt aanvaardt, de unieke maximum BSST verankerd aan zijn linkerkind de unieke maximum BSST verankerd aan zijn rechterkind, en verwijzingen naar de meest linkse en meest rechtse elementen van deze BSSTs. Het vernietigt de ingangen (vermijdbare met persistente datastructuren) en construeert het unieke maximum BSST geworteld in de bepaalde knoop, samen met de minimum en maximum elementen. Alle BSST nodes zijn geannoteerd met het aantal nakomelingen. Net als voorheen, wordt deze procedure herhaaldelijk opgeroepen uit een post-order traversal. Om de sub-boom terug te krijgen, denk aan de wortel van de grootste BSST; reconstrueren het vereist slechts een eenvoudige traversal.

Ik zal alleen de behandeling van de linker BSST; Rechts is symmetrisch. Als de wortel van de linker BSST groter is dan de nieuwe wortel, dan is de hele sub-boom is verwijderd, en de nieuwe wortel wordt nu meest linkse. Anders wordt de oude meest linkse knooppunt nog steeds meest linkse. Uitgaande van de meest rechtse knooppunt van de linker BSST en omhoog bewegen, vindt de eerste knoop die kleiner is dan of gelijk is aan de wortel. Haar recht kind moet worden verwijderd; Let nu dat als gevolg van het pand BST, geen andere knooppunten moeten gaan! Ga naar de root van de linker BSST, het bijwerken van de tellingen om de verwijdering te reflecteren.

De reden is O (n) dat ondanks de lus, weerskanten in de oorspronkelijke structuur wordt in wezen slechts één keer doorlopen.


EDIT: collectief, de paden doorlopen zijn de maximale rechte lijn paden in een BST, met uitzondering van de linker wervelkolom en de juiste wervelkolom. Bijvoorbeeld op de ingang

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

Hier zijn de recursieve aanroepen waarop elke rand doorlopen:

              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
antwoordde op 03/07/2010 om 17:46
bron van user

stemmen
1

GROOTSTE binary search BOOM IN EEN binaire boom:

Er zijn twee manieren kunnen we dit probleem aan te pakken,

i) Grootste BST niet geïnduceerd (Uit een knooppunt, moeten al zijn kinderen niet voldoen aan de BST voorwaarde)

ii) Grootste BST geïnduceerde (Uit een knooppunt, zal al zijn kinderen voldoen aan de BST voorwaarde)

We zullen discussiëren over de grootste BST (niet geïnduceerd) hier. We zullen bottom-up benadering (Voeg orde traversal) om dit op te lossen volgen.

a) Bereik het eindknooppunt

b) een boomstructuur (uit het blad) een TreeNodeHelper voorwerp waarvan de volgende gebieden heeft terugkeren.

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) het begin van het eindknooppunt knooppunten = 1, isBST = true, MINVALUE = MAXVALUE = node.data. En verder, de knooppunten telling zal worden verhoogd als het voldoet aan de BST conditie.

d) Met behulp van deze, zullen we de BST staat met huidige knooppunt controleren. En we zullen hetzelfde herhalen tot root.

e) Van elk knooppunt twee objecten worden geretourneerd. één voor last maximale BST en een voor actuele BST bevredigend nodes. Dus vanaf elk knooppunt (boven blad) (2 + 2) = 4 (2 voor linker deelboom en 2 voor rechts subboom) objecten worden vergeleken en twee geretourneerd.

f) De uiteindelijke maximale knooppunt object root de grootste BST zijn

PROBLEEM:

Er is een probleem in deze benadering. Tijdens het volgen van deze aanpak, als een subboom niet voldoet aan de BST staat met het huidige knooppunt, kunnen we niet gewoon de substructuur negeren (zelfs het minder aantal knooppunten). Bijvoorbeeld

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

Van de bladknooppunten (20110) objecten worden getest met het knooppunt (105), het aan de voorwaarde. Maar als het knooppunt bereikt (95) het blad knooppunt (20) niet voldoet aan de BST conditie. Aangezien deze oplossing voor BST (niet geïnduceerde) moeten we niet knooppunt (105) en het knooppunt (110) dat voldoet aan de voorwaarde negeren. Dus vanaf het knooppunt (95) hebben we weer terug te krabbelen testen van BST staat en om hen te vangen knooppunten (105, 110).

De volledige code voor deze implementatie is beschikbaar in deze link

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

antwoordde op 27/03/2014 om 00:48
bron van user

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