किसी दिए गए द्विआधारी पेड़ के लिए अधिकतम द्विआधारी खोज उप पेड़ लगता है

वोट
13

किसी दिए गए द्विआधारी पेड़ के लिए, सबसे बड़ा सबट्री जो भी द्विआधारी खोज वृक्ष है?

उदाहरण:

इनपुट:

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

आउटपुट:

                   50
                  /   \
                 25   75
                / \   /
               15 35  65
02/07/2010 को 06:15
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


7 जवाब

वोट
0

एक द्विआधारी खोज वृक्ष यदि आप एक में-आदेश Traversal कर आप एक क्रमबद्ध परिणाम दे देंगे। तो, पूरे द्विआधारी पेड़ के लिए एक में आदेश ट्रावर्सल है। सबसे लंबे समय तक हल कर अनुक्रम अपने सबसे बड़ा द्विआधारी खोज उप पेड़ है।

  • तत्वों की एक inorder ट्रावर्सल (यात्रा वाम, यात्रा जड़ यात्रा का अधिकार) है
  • ऐसा करते समय, नोड डेटा प्राप्त तुलना कि क्या पिछले नोड डेटा अगले डेटा की तुलना में कम है। यदि हां, तो 1. स्टोर शुरू नोड द्वारा काउंटर बढ़ाने के।
  • जब तुलना में विफल रहता है, अंत नोड की दुकान और 0 के लिए काउंटर रीसेट
  • एक सरणी संरचना में यह जानकारी (काउंटर, शुरू, अंत) नोड स्टोर बाद में पता लगाने के लिए जो अधिकतम मूल्य हो रही है और है कि आप सबसे लंबे समय तक द्विआधारी खोज उप पेड़ दे देंगे
02/07/2010 को 06:26
का स्रोत उपयोगकर्ता

वोट
2

दिलचस्प सवाल!

मेरे पहले प्रयास moronically गलत था!

यहाँ एक और प्रयास (उम्मीद इस बार को सही) है।

मैं पेड़ से जुड़ा हुआ है यह सोचते हैं रहा हूँ।

पेड़ की प्रत्येक नोड n के लिए मान लीजिए, आप एन, एस के वंशज का एक सेट था n संपत्ति के साथ कि

  • के लिए एस के प्रत्येक सदस्य एक्स एन , एन से एक्स के लिए अद्वितीय पथ एक द्विआधारी खोज वृक्ष (यह केवल एक रास्ता है, लेकिन आप अभी भी यह एक पेड़ पर विचार कर सकते हैं) है।

  • एक्स के हर वंशज y के लिए, जैसे कि y के लिए n से पथ एक BST है, वाई एस में है n

के नोड्स एस सेट n , आप सबसे बड़ा BST n में निहित देता है।

हम एस निर्माण कर सकते हैं n पेड़ पर गहराई पहले खोज कर रही है, और पथ जानकारी (वर्तमान नोड के लिए जड़ से पथ) में पासिंग और मार्ग के किनारे उलटे पांव लौटने से रास्ते में नोड्स के सेट को अपडेट करके प्रत्येक नोड के लिए।

जब हम एक नोड जाते हैं तो हम पथ चलना, और देखें कि क्या BST संपत्ति संतुष्ट है के लिए पथ के उस भाग के अब तक ऊपर चला गया। यदि हां, तो हम पथ हम सिर्फ करने के लिए चला गया के नोड की इसी सेट करने के लिए वर्तमान नोड जोड़ें। हम पथ पल BST संपत्ति का उल्लंघन किया है घूमना बंद। जांच की जा रही है, तो पथ सेगमेंट हम अब तक चला गया एक BST हे में किया जा सकता (1) समय, एक ओ (PATH_LENGTH) समय कुल संसाधन समय के लिए, प्रत्येक नोड के लिए है।

अंत में, प्रत्येक नोड अपने इसी एस होगा n आबादी। हम पेड़ अब चलना और एस के सबसे बड़े मूल्य के साथ नोड चुन सकते हैं n

समय इस लिए लिया नोड्स की गहराई का योग (सबसे खराब स्थिति में) है, और है कि औसत के मामले में ओ (nlogn) है (की धारा 5.2.4 देखने http://www.toves.org/books/ डेटा / ch05-पेड़ / index.html ), लेकिन O (n ^ 2) सबसे खराब स्थिति में।

शायद सेट अद्यतन करने के लिए एक चालाक रास्ता सबसे ज्यादा मामले समय में कमी की गारंटी देगा।

छद्म कोड की तरह कुछ हो सकता है:

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

}
02/07/2010 को 14:13
का स्रोत उपयोगकर्ता

वोट
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

BlueRaja के रूप में कहे अनुसार, इस एल्गोरिथ्म सही नहीं है।

यह वास्तव में बुलाया जाना चाहिए GetLargestSortedBinarySubtreeThatCanBeRecursivelyConstructedFromMaximalSortedSubtrees

02/07/2010 को 19:46
का स्रोत उपयोगकर्ता

वोट
3

पिछले एल्गोरिथ्म (संशोधन देखें) था O(n^2)- हम करने के लिए यह सामान्य कर सकते हैं O(n log n)तथ्य यह है कि देख द्वारा:

  1. यदि ख सबसे बड़ा BST की जड़ है और b.left.value < b.value, फिर b.leftभी BST में (के लिए एक ही है b.right.value ≥ b.value)
  2. यदि ख सबसे बड़ा BST की जड़ है और एक BST में भी है, तो एक और ख के बीच प्रत्येक नोड BST में है।

तो अगर सी ए और बी के बीच है, और ग BST ख द्वारा निहित में नहीं है, न तो एक है (की वजह से (2)) । इस तथ्य का उपयोग करना, हम आसानी से लगा सकते हैं कि एक नोड BST किसी भी पूर्वज द्वारा निहित है। हम अपने पूर्वजों की एक सूची के साथ हमारे समारोह में एक नोड पास करके यह करूँगा, और संबद्ध मिनट / maxValues वर्तमान बच्चे नोड यदि वास्तव में है कि पूर्वज सबसे बड़ा BST की जड़ थे को पूरा करने के लिए होता है कि (हम ll इस सूची फोन ancestorList)। हम में संभावित-जड़ों का पूरा संग्रह संग्रहीत करेंगेoverallRootsList

चलो एक संरचना potentialRoot कहा जाता है इस प्रकार परिभाषित करते हैं:

प्रत्येक potentialRoot निम्न मान शामिल हैं:
* नोड : नोड हम BST की जड़ के लिए विचार कर रहे हैं
* MINVALUE और MAXVALUE : सीमा एक और नोड के बीच पड़ना चाहिए BST नोड द्वारा निहित का हिस्सा बनने के (प्रत्येक नोड के लिए अलग अलग)
* subNodes : सबसे बड़ा BST में नोड्स के बाकी की एक सूची नोड द्वारा निहित

छद्म कोड इस तरह दिखता है (ध्यान दें कि सभी सूचियों का उल्लेख 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)

अंत में overallRootsListकी एक सूची हो जाएगा n, subNodes की एक सूची के साथ प्रत्येक potentialRoots। सबसे बड़ा subNodes सूची के साथ एक अपने BST है।

देखते हैं के बाद से <treeHeight में महत्व देता है ancestorList, तो (यह मानते हुए पेड़ संतुलित है), एल्गोरिथ्म में चलता हैO(n log n)

02/07/2010 को 20:21
का स्रोत उपयोगकर्ता

वोट
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)

ठीक एक बार हर एक पेड़ नोड पर लग रहा है, इसलिए हे (एन) में चलता है।

संपादित करें: Crud, इस पर विचार नहीं करता इसे बाहर एक सबट्री के कुछ हिस्सों को छोड़ कर सकते हैं। जब मैं सबट्री पढ़ा, मैं "पूरे पेड़ कुछ नोड पर निहित" ग्रहण किया। मैं वापस आने के बाद में इसे ठीक कर सकते हैं।

03/07/2010 को 01:15
का स्रोत उपयोगकर्ता

वोट
4

इस उत्तर पूर्व में निहित एक O (n लॉग ऑन एन) लिंक / कटौती के पेड़ के आधार पर एल्गोरिथ्म। यहाँ एक सरल है हे (एन) समाधान।

कोर एक प्रक्रिया है जो एक नोड को स्वीकार करता है, अनन्य अधिकतम BSST अपनी बाईं बच्चे पर निहित, अनन्य अधिकतम BSST अपने अधिकार बच्चे पर सबसे बाईं ओर और सही इनमें से सबसे BSSTs के तत्वों को जड़ें, और संकेत दिए गए। यह अपने आदानों (लगातार डेटा संरचनाओं के साथ परिहार्य) नष्ट कर देता है और उसके न्यूनतम और अधिकतम तत्वों के साथ एक साथ दिए गए नोड पर निहित अनन्य अधिकतम BSST निर्माण करती है,। सभी ने कहा BSST नोड्स वंशजों की संख्या से एनोटेट। पहले की तरह, इस प्रक्रिया के बाद आदेश ट्रावर्सल से बार-बार कहा जाता है। उप पेड़ की वसूली करने के लिए, सबसे बड़ा BSST की जड़ याद; यह पुनर्निर्माण केवल एक साधारण ट्रेवर्सल की आवश्यकता है।

मैं चला गया BSST केवल इस तरह मानते हैं; सही सममित है। यदि छोड़ दिया BSST की जड़ नया रूट से अधिक है, तो पूरे उप पेड़ हटा दिया जाता है, और नया रूट अब बाएं सबसे है। अन्यथा, पुराने सबसे बाईं ओर नोड अभी भी एकदम बाएँ है। छोड़ दिया BSST के दाएँ सबसे नोड से शुरू और ऊपर की ओर बढ़ रहा है, पहले नोड कि जड़ से कम या उसके बराबर है पाते हैं। इसका सही बच्चे हटा दिया जाना चाहिए; अब ध्यान दें कि BST संपत्ति की वजह से, कोई अन्य नोड्स जाने की जरूरत है! बाईं BSST की जड़ के लिए आगे बढ़ें, मायने रखता है अद्यतन करने के हटाए जाने को प्रतिबिंबित करने के।

कारण यह हे है (एन) कि पाश के बावजूद, मूल पेड़ में प्रत्येक किनारे संक्षेप में केवल एक बार चल रहा है।


संपादित करें: सामूहिक रूप से, रास्तों चल अधिक से अधिक सरल-रेखा एक BST में पथ, बाईं रीढ़ की हड्डी और सही रीढ़ की हड्डी के अलावा हैं। उदाहरण के लिए, इनपुट पर

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

यहाँ पुनरावर्ती कॉल जिस पर प्रत्येक किनारे चल रहा है कर रहे हैं:

              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
03/07/2010 को 17:46
का स्रोत उपयोगकर्ता

वोट
1

एक द्विआधारी पेड़ में सबसे बड़े द्विआधारी खोज वृक्ष:

दो तरीके हम इस समस्या से संपर्क कर सकते हैं,

i) सबसे बड़ा BST प्रेरित नहीं (एक नोड से, अपने सभी बच्चों को BST शर्त पूरी नहीं की जरूरत नहीं है)

ii) सबसे बड़ा BST प्रेरित (एक नोड से, अपने सभी बच्चों को BST हालत को संतुष्ट करेगा)

हम सबसे बड़ा BST (प्रेरित नहीं) के बारे में यहाँ पर चर्चा करेंगे। हम नीचे से ऊपर दृष्टिकोण (पोस्ट आदेश ट्रावर्सल) इस हल करने के लिए का पालन करेंगे।

क) पत्ती नोड तक पहुंचें

ख) एक वृक्ष नोड (पत्ती से) एक TreeNodeHelper वस्तु जो उस में निम्नलिखित क्षेत्रों है वापस आ जाएगी।

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

ग) शुरू में पत्ती नोड से, नोड्स = 1, isBST = सच है, MINVALUE = MAXVALUE = node.data। और आगे, नोड्स गिनती अगर यह BST हालत संतुष्ट बढ़ जाएगी।

घ) इस की मदद से, हम वर्तमान नोड के साथ BST हालत की जाँच करेगा। और हम जड़ तक एक ही दोहराया जाएगा।

ई) प्रत्येक नोड से दो वस्तुओं लौटा दी जाएगी। पिछले अधिकतम BST और वर्तमान BST संतोषजनक नोड्स के लिए एक और एक के लिए एक। तो (पत्ता ऊपर) प्रत्येक नोड (2 + 2) = 4 (2 बाईं सबट्री के लिए और 2 सही उप पेड़ के लिए) से वस्तुओं तुलना में किया जाएगा और दो लौटा दी जाएगी।

च) जड़ से अंतिम अधिकतम नोड वस्तु सबसे बड़ा BST हो जाएगा

मुसीबत:

इस दृष्टिकोण में कोई समस्या है। इस दृष्टिकोण का अनुसरण करते हुए, यदि एक सबट्री वर्तमान नोड के साथ BST हालत संतोषजनक नहीं है, हम बस सबट्री नजरअंदाज नहीं कर सकते (यहां तक ​​कि यह नोड्स की कम संख्या है)। उदाहरण के लिए

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

पत्र-गांठ (20,110) वस्तुओं नोड (105) के साथ परीक्षण किया जाएगा, यह शर्त संतुष्ट करता है। लेकिन जब यह नोड तक पहुँच जाता है (95) पत्ती नोड (20) BST शर्त पूरी नहीं करता है। चूंकि यह समाधान BST (प्रेरित नहीं) के लिए है हम नोड (105) और नोड (110) जो हालत को संतुष्ट करता अनदेखी नहीं करनी चाहिए। तो नोड (95) से हम BST हालत का परीक्षण फिर से पीछे और उन नोड्स (105, 110) को पकड़ने के लिए की है।

इस कार्यान्वयन के लिए पूरा कोड इस लिंक में उपलब्ध है

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

27/03/2014 को 00:48
का स्रोत उपयोगकर्ता

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