ऑप्टिमम तरीके से बाइनरी सर्च ट्री में kth सबसे छोटा तत्व खोजें


112

मुझे किसी भी स्थिर / वैश्विक चर का उपयोग किए बिना बाइनरी सर्च ट्री में kth सबसे छोटा तत्व खोजने की आवश्यकता है। इसे कुशलता से कैसे हासिल किया जाए? मेरे मन में जो समाधान है वह ओ (एन) में ऑपरेशन कर रहा है, सबसे खराब स्थिति है क्योंकि मैं पूरे पेड़ के इनवर्टर ट्रावेल करने की योजना बना रहा हूं। लेकिन गहराई से मुझे लगता है कि मैं यहां BST संपत्ति का उपयोग नहीं कर रहा हूं। क्या मेरा धारणात्मक समाधान सही है या क्या कोई बेहतर विकल्प उपलब्ध है?


7
क्या पेड़ संतुलित है?
kennytm

यह। लेकिन अगर यह संतुलित था, तो क्या एक इष्टतम तरीका है?
ब्रैगबॉय

1
यदि आप "ऑर्डर स्टैटिस्टिक्स" पर एक खोज करते हैं, तो आपको वह मिलेगा जो आपको चाहिए।
RAL

मैं नीचे दिए गए अधिकांश उत्तरों को महसूस करता हूं, जबकि सही में यह धोखा है कि वे किसी प्रकार के वैश्विक चर का उपयोग कर रहे हैं (चाहे वह किसी पूर्णांक का संदर्भ हो, या एक चर जो घटित हो और वापस आ जाए)। यदि उनमें से किसी को भी अनुमति नहीं है, तो मैं किसी भी संदर्भ में पारित किए बिना पुनरावृत्ति का उपयोग करूंगा।
हेनले चिउ

जवाबों:


170

यहाँ सिर्फ विचार की एक रूपरेखा है:

BST में, नोड के बाएँ उप-खंड में Tसंग्रहीत किए गए मान से छोटे तत्व होते हैं T। यदि kबाईं सबट्री में तत्वों की संख्या से कम है, तो kवें सबसे छोटे तत्व को बाएं सबट्री से संबंधित होना चाहिए। अन्यथा, यदि kबड़ा है, तो kवें सबसे छोटा तत्व सही उपप्रकार में है।

हम BST को संवर्धित कर सकते हैं कि प्रत्येक नोड में इसके बायीं ओर उपरी में तत्वों की संख्या जमा हो (मान लें कि किसी दिए गए नोड के बाएँ उपप्रकार में वह नोड शामिल है)। जानकारी के इस टुकड़े के साथ, बाएं सबट्री में तत्वों की संख्या को बार-बार पूछकर पेड़ को पीछे हटाना आसान है, यह तय करने के लिए कि क्या बाएं या दाएं सबट्री में पुनरावृत्ति करना है।

अब, मान लें कि हम नोड T पर हैं:

  1. यदि k == num_elements (T की बाईं सबट्री) , तो हम जो उत्तर खोज रहे हैं, वह नोड में मूल्य है T
  2. यदि k> num_elements (T के बाएं सबट्री) , तो जाहिर है हम बाएं सबट्री को अनदेखा कर सकते हैं, क्योंकि वे तत्व भी kवें से छोटे होंगे। तो, हम k - num_elements(left subtree of T)सही सबट्री के सबसे छोटे तत्व को खोजने के लिए समस्या को कम करते हैं ।
  3. यदि k <num_elements (T के बाएं सबट्री) , तो kवें सबसे छोटा कहीं बाएं सबट्री में है, इसलिए हम बाएं सबट्री में kवें सबसे छोटे तत्व को खोजने के लिए समस्या को कम करते हैं ।

जटिलता विश्लेषण:

इसमें O(depth of node)समय लगता है, जो O(log n)एक संतुलित बीएसटी पर सबसे खराब स्थिति में होता है, या O(log n)औसतन एक यादृच्छिक बीएसटी के लिए।

एक BST को O(n)भंडारण की आवश्यकता होती है, और O(n)तत्वों की संख्या के बारे में जानकारी संग्रहीत करने के लिए इसे दूसरा लेता है । सभी BST ऑपरेशन में O(depth of node)समय लगता है, और O(depth of node)नोड्स के सम्मिलन, विलोपन या रोटेशन के लिए "तत्वों की संख्या" को बनाए रखने के लिए अतिरिक्त समय लगता है । इसलिए, बाएं सबट्री में तत्वों की संख्या के बारे में जानकारी संग्रहीत करने से BST का स्थान और समय जटिलता बनी रहती है।


59
Nth के सबसे छोटे आइटम को खोजने के लिए, आपको केवल बाईं उप-ट्री के आकार को संग्रहीत करने की आवश्यकता है। आप सही उप-पेड़ के आकार का उपयोग करेंगे Iif जिसे आप Nth की सबसे बड़ी वस्तु ढूंढने में सक्षम होना चाहते हैं। वास्तव में, आप इसे कम खर्चीला बना सकते हैं: जड़ में पेड़ का कुल आकार, और बाईं उप-पेड़ का आकार। जब आपको सही उप-पेड़ के आकार की आवश्यकता होती है, तो आप बाईं ओर के आकार को कुल आकार से घटा सकते हैं।
जेरी कॉफ़िन

37
इस तरह के संवर्धित BST को 'ऑर्डर सांख्यिकी ट्री' कहा जाता है।
डैनियल

10
@Ivlad: चरण 2 में: मुझे लगता है कि "k - num_elements" को "k - num_elements -1" होना चाहिए, क्योंकि आपको रूट एलिमेंट भी शामिल करना है।
समझे

1
@understack - अगर आप रूट को सबट्री का हिस्सा मानते हैं तो नहीं।
IVlad

16
यदि पेड़ में "बाएँ और दाएँ सबट्री में तत्वों की संख्या" वाला कोई फ़ील्ड शामिल नहीं है, तो विधि बिग बी (n) के रूप में समाप्त हो जाएगी क्योंकि आपको प्रत्येक नोड पर दाएँ या बाएँ सबट्री चलने की आवश्यकता होगी वर्तमान नोड के k सूचकांक की गणना करें।
रॉबर्ट एस। बार्न्स

68

एक सरल समाधान एक इनवर्टर ट्रैवर्सल करना होगा और वर्तमान में मुद्रित किए जाने वाले तत्व को ट्रैक करना होगा (इसे प्रिंट किए बिना)। जब हम k तक पहुंचते हैं, तो तत्व को प्रिंट करें और बाकी ट्री ट्रैवर्सल को छोड़ दें।

void findK(Node* p, int* k) {
  if(!p || k < 0) return;
  findK(p->left, k);
  --k;
  if(k == 0) { 
    print p->data;
    return;  
  } 
  findK(p->right, k); 
}

1
+1: विचार सही दिशा में है, लेकिन कुछ ढीले छोरों को कसने की आवश्यकता हो सकती है; देखें stackoverflow.com/a/23069077/278326
अरुण

1
मुझे यह समाधान पसंद है, क्योंकि बीएसटी पहले से ही ऑर्डर किया गया है, एक ट्रावर्सल पर्याप्त होना चाहिए।
मर्लिन

3
यदि n इस पेड़ की कुल संख्या के करीब है, तो आपका एल्गोरिथ्म समाप्त होने में O (n) समय लेगा, जो चयनित उत्तर के लिए खराब है O (लॉग एन)
Spark8006

13
public int ReturnKthSmallestElement1(int k)
    {
        Node node = Root;

        int count = k;

        int sizeOfLeftSubtree = 0;

        while(node != null)
        {

            sizeOfLeftSubtree = node.SizeOfLeftSubtree();

            if (sizeOfLeftSubtree + 1 == count)
                return node.Value;
            else if (sizeOfLeftSubtree < count)
            {
                node = node.Right;
                count -= sizeOfLeftSubtree+1;
            }
            else
            {
                node = node.Left;
            }
        }

        return -1;
    }

यह C # में मेरा कार्यान्वयन एल्गोरिथम के ऊपर आधारित है, मैंने सोचा था कि मैं इसे पोस्ट करूंगा ताकि लोग मेरे लिए बेहतर काम कर सकें

आईवीएलडी धन्यवाद


11

एक सरल समाधान एक इनवर्टर ट्रैवर्स करना होगा और वर्तमान में काउंटर के साथ मुद्रित होने वाले तत्व का ट्रैक रखना होगा। जब हम k तक पहुंचते हैं, तो तत्व प्रिंट करें। रनटाइम O (n) है। याद रखें कि फ़ंक्शन रिटर्न प्रकार शून्य नहीं हो सकता है, प्रत्येक पुनरावर्ती कॉल के बाद इसका k का अद्यतन मान वापस करना होगा। इसका एक बेहतर समाधान प्रत्येक नोड पर एक सॉर्ट किए गए स्थिति मूल्य के साथ एक संवर्धित BST होगा।

public static int kthSmallest (Node pivot, int k){
    if(pivot == null )
        return k;   
    k = kthSmallest(pivot.left, k);
    k--;
    if(k == 0){
        System.out.println(pivot.value);
    }
    k = kthSmallest(pivot.right, k);
    return k;
}

मुझे लगता है कि संवर्धित बीएसटी के साथ तुलना में आपका समाधान अंतरिक्ष की जटिलता के मामले में बेहतर है।
zach

के-वें सबसे छोटा तत्व मिलने के बाद भी खोज बंद नहीं होती है।
विनीत चित्तेती

10

// पुनरावृत्ति के बिना एक जावा संस्करण जोड़ें

public static <T> void find(TreeNode<T> node, int num){
    Stack<TreeNode<T>> stack = new Stack<TreeNode<T>>();

    TreeNode<T> current = node;
    int tmp = num;

    while(stack.size() > 0 || current!=null){
        if(current!= null){
            stack.add(current);
            current = current.getLeft();
        }else{
            current = stack.pop();
            tmp--;

            if(tmp == 0){
                System.out.println(current.getValue());
                return;
            }

            current = current.getRight();
        }
    }
}

मैं इस समाधान और इसी पुनरावर्ती को पसंद करता हूं। ईमानदारी से, इस प्रश्न के अधिकांश उत्तर पढ़ने के लिए बहुत भ्रामक / जटिल हैं।
हेनले चिउ

मैं इस समाधान प्यार करता हूँ! स्पष्ट और महान!
रगल

यह समाधान पेड़ 'इन-ऑर्डर' का पता लगा रहा है और नोड पर जाने के बाद एक काउंटर को कम कर रहा है, बाद में जब शून्य के बराबर हो जाता है तो रुक जाता है। सबसे खराब स्थिति तो ऑर्डर O (n) की है। @ IVlad के पुनरावर्ती समाधानों के साथ सबसे इष्टतम तुलना नहीं है जिसका सबसे खराब मामला O (लॉग एन) लेता है
जॉर्ज पी।


4

बस एक सादे बाइनरी सर्च ट्री को देखते हुए, आप जो कर सकते हैं, वह सबसे छोटे से शुरू होता है, और सही नोड खोजने के लिए ऊपर की ओर बढ़ता है।

यदि आप बहुत बार ऐसा करने जा रहे हैं, तो आप प्रत्येक नोड में एक विशेषता जोड़ सकते हैं जो यह दर्शाता है कि उसके बाएं उप-पेड़ में कितने नोड हैं। इसके प्रयोग से, आप पेड़ को सीधे सही नोड तक ले जा सकते हैं।


4

पुनरावर्ती आदेश एक काउंटर के साथ चलो

Time Complexity: O( N ), N is the number of nodes
Space Complexity: O( 1 ), excluding the function call stack

विचार @prasadvk समाधान के समान है, लेकिन इसकी कुछ कमियां हैं (नीचे नोट्स देखें), इसलिए मैं इसे एक अलग उत्तर के रूप में पोस्ट कर रहा हूं।

// Private Helper Macro
#define testAndReturn( k, counter, result )                         \
    do { if( (counter == k) && (result == -1) ) {                   \
        result = pn->key_;                                          \
        return;                                                     \
    } } while( 0 )

// Private Helper Function
static void findKthSmallest(
    BstNode const * pn, int const k, int & counter, int & result ) {

    if( ! pn ) return;

    findKthSmallest( pn->left_, k, counter, result );
    testAndReturn( k, counter, result );

    counter += 1;
    testAndReturn( k, counter, result );

    findKthSmallest( pn->right_, k, counter, result );
    testAndReturn( k, counter, result );
}

// Public API function
void findKthSmallest( Bst const * pt, int const k ) {
    int counter = 0;
    int result = -1;        // -1 := not found
    findKthSmallest( pt->root_, k, counter, result );
    printf("%d-th element: element = %d\n", k, result );
}

नोट्स (@ प्रसाद के समाधान से मतभेद):

  1. if( counter == k )परीक्षण तीन स्थानों पर आवश्यक है : (ए) बाएं उप-उपशीर्षक के बाद, (बी) रूट के बाद, और (सी) सही उपप्रति के बाद। यह सुनिश्चित करने के लिए है कि kth तत्व सभी स्थानों के लिए खोजा गया है , अर्थात चाहे वह जिस भी स्थान पर स्थित हो।

  2. if( result == -1 )केवल परिणाम तत्व को मुद्रित करने के लिए परीक्षण की आवश्यकता होती है , अन्यथा केथ से शुरू होने वाले सभी तत्व जड़ तक छोटे होते हैं।


इस समाधान के लिए समय की जटिलता है O(k + d), जहां dपेड़ की अधिकतम गहराई है। इसलिए यह एक वैश्विक चर का उपयोग करता है counterलेकिन यह इस प्रश्न के लिए अवैध है।
वैलेंटाइन शर्लिन

हाय अरुण, क्या आप कृपया एक उदाहरण से समझा सकते हैं। मैं इसे विशेष रूप से आपका पहला बिंदु नहीं समझ रहा हूं।
एंडी And

3

संतुलित खोज वृक्ष के लिए नहीं , यह O (n) लेता है ।

के लिए संतुलित खोज पेड़, यह लेता है ओ (k + लॉग एन) सबसे खराब स्थिति में है लेकिन सिर्फ हे (के) में परिशोधित भावना।

प्रत्येक नोड के लिए अतिरिक्त पूर्णांक का प्रबंधन और प्रबंधन: उप-वृक्ष का आकार O (लॉग एन) समय जटिलता देता है। इस तरह के संतुलित खोज वाले पेड़ को आमतौर पर रैंकट्री कहा जाता है।

सामान्य तौर पर, समाधान होते हैं (पेड़ पर आधारित नहीं)।

सादर।


1

यह अच्छी तरह से काम करता है: स्थिति: वह सरणी है जो रखती है कि तत्व पाया जाता है या नहीं। k: पाया जाने वाला kth तत्व है। गिनती: पेड़ के चक्कर के दौरान फंसे हुए नोड्स की संख्या का ट्रैक रखता है।

int kth(struct tree* node, int* status, int k, int count)
{
    if (!node) return count;
    count = kth(node->lft, status, k, count);  
    if( status[1] ) return status[0];
    if (count == k) { 
        status[0] = node->val;
        status[1] = 1;
        return status[0];
    }
    count = kth(node->rgt, status, k, count+1);
    if( status[1] ) return status[0];
    return count;
}

1

हालांकि यह निश्चित रूप से समस्या का इष्टतम समाधान नहीं है, यह एक और संभावित समाधान है जो मुझे लगा कि कुछ लोगों को दिलचस्प लग सकता है:

/**
 * Treat the bst as a sorted list in descending order and find the element 
 * in position k.
 *
 * Time complexity BigO ( n^2 )
 *
 * 2n + sum( 1 * n/2 + 2 * n/4 + ... ( 2^n-1) * n/n ) = 
 * 2n + sigma a=1 to n ( (2^(a-1)) * n / 2^a ) = 2n + n(n-1)/4
 *
 * @param t The root of the binary search tree.
 * @param k The position of the element to find.
 * @return The value of the element at position k.
 */
public static int kElement2( Node t, int k ) {
    int treeSize = sizeOfTree( t );

    return kElement2( t, k, treeSize, 0 ).intValue();
}

/**
 * Find the value at position k in the bst by doing an in-order traversal 
 * of the tree and mapping the ascending order index to the descending order 
 * index.
 *
 *
 * @param t Root of the bst to search in.
 * @param k Index of the element being searched for.
 * @param treeSize Size of the entire bst.
 * @param count The number of node already visited.
 * @return Either the value of the kth node, or Double.POSITIVE_INFINITY if 
 *         not found in this sub-tree.
 */
private static Double kElement2( Node t, int k, int treeSize, int count ) {
    // Double.POSITIVE_INFINITY is a marker value indicating that the kth 
    // element wasn't found in this sub-tree.
    if ( t == null )
        return Double.POSITIVE_INFINITY;

    Double kea = kElement2( t.getLeftSon(), k, treeSize, count );

    if ( kea != Double.POSITIVE_INFINITY )
        return kea;

    // The index of the current node.
    count += 1 + sizeOfTree( t.getLeftSon() );

    // Given any index from the ascending in order traversal of the bst, 
    // treeSize + 1 - index gives the
    // corresponding index in the descending order list.
    if ( ( treeSize + 1 - count ) == k )
        return (double)t.getNumber();

    return kElement2( t.getRightSon(), k, treeSize, count );
}

1

हस्ताक्षर:

Node * find(Node* tree, int *n, int k);

इस रूप में कॉल करें:

*n = 0;
kthNode = find(root, n, k);

परिभाषा:

Node * find ( Node * tree, int *n, int k)
{
   Node *temp = NULL;

   if (tree->left && *n<k)
      temp = find(tree->left, n, k);

   *n++;

   if(*n==k)
      temp = root;

   if (tree->right && *n<k)
      temp = find(tree->right, n, k);

   return temp;
}

1

खैर यहाँ मेरे 2 सेंट है ...

int numBSTnodes(const Node* pNode){
     if(pNode == NULL) return 0;
     return (numBSTnodes(pNode->left)+numBSTnodes(pNode->right)+1);
}


//This function will find Kth smallest element
Node* findKthSmallestBSTelement(Node* root, int k){
     Node* pTrav = root;
     while(k > 0){
         int numNodes = numBSTnodes(pTrav->left);
         if(numNodes >= k){
              pTrav = pTrav->left;
         }
         else{
              //subtract left tree nodes and root count from 'k'
              k -= (numBSTnodes(pTrav->left) + 1);
              if(k == 0) return pTrav;
              pTrav = pTrav->right;
        }

        return NULL;
 }

0

यह वही है जो मैं हालांकि और यह काम करता है। यह ओ (लॉग एन) में चलेगा

public static int FindkThSmallestElemet(Node root, int k)
    {
        int count = 0;
        Node current = root;

        while (current != null)
        {
            count++;
            current = current.left;
        }
        current = root;

        while (current != null)
        {
            if (count == k)
                return current.data;
            else
            {
                current = current.left;
                count--;
            }
        }

        return -1;


    } // end of function FindkThSmallestElemet

3
मुझे नहीं लगता कि यह समाधान काम करेगा। क्या होगा यदि Kth सबसे छोटा है पेड़ के नोड के सही उप पेड़ में?
अनिल विश्नोई

0

अच्छी तरह से हम केवल क्रम ट्रैवर्सल का उपयोग कर सकते हैं और स्टैक पर विज़िट किए गए तत्व को धक्का दे सकते हैं। उत्तर पाने के लिए कई बार पॉप k।

हम भी तत्वों के बाद बंद कर सकते हैं


1
यह एक इष्टतम समाधान नहीं है
Bragboy

0

संपूर्ण बीएसटी मामले का समाधान: -

Node kSmallest(Node root, int k) {
  int i = root.size(); // 2^height - 1, single node is height = 1;
  Node result = root;
  while (i - 1 > k) {
    i = (i-1)/2;  // size of left subtree
    if (k < i) {
      result = result.left;
    } else {
      result = result.right;
      k -= i;
    }  
  }
  return i-1==k ? result: null;
}

0

लिनक्स कर्नेल में एक उत्कृष्ट संवर्धित लाल-काले पेड़ की डेटा संरचना है जो लाइनक्स / लिब / rbtree.c में ओ (लॉग एन) में रैंक-आधारित संचालन का समर्थन करती है।

Http://code.google.com/p/refolding/source/browse/trunk/core/src/main/java/it/unibo/refolding/alg/RbTree.java पर एक बहुत कच्चा जावा पोर्ट भी पाया जा सकता है । RbRoot.java और RbNode.java के साथ। N'th एलिमेंट को RbNode.nth (RbNode नोड, int n) कहकर पेड़ की जड़ में पास करके प्राप्त किया जा सकता है।


0

यहाँ में एक संक्षिप्त संस्करण है सी # कि रिटर्न k- वां सबसे छोटा तत्व है, लेकिन एक रेफरी तर्क (यह @prasadvk रूप में एक ही तरीका है) के रूप में में कश्मीर गुजर आवश्यक है:

Node FindSmall(Node root, ref int k)
{
    if (root == null || k < 1)
        return null;

    Node node = FindSmall(root.LeftChild, ref k);
    if (node != null)
        return node;

    if (--k == 0)
        return node ?? root;
    return FindSmall(root.RightChild, ref k);
}

यह ओ (लॉग एन) सबसे छोटा नोड खोजने के लिए है, और फिर ओ (के) को के-वें नोड के लिए पार करना है, इसलिए यह ओ (के + लॉग एन) है।


जावा संस्करण के बारे में कैसे?
हेनले चिउ


0

मुझे एक बेहतर एल्गोरिथ्म नहीं मिला..तो एक लिखने का फैसला किया :) अगर यह गलत है तो मुझे सुधारें।

class KthLargestBST{
protected static int findKthSmallest(BSTNode root,int k){//user calls this function
    int [] result=findKthSmallest(root,k,0);//I call another function inside
    return result[1];
}
private static int[] findKthSmallest(BSTNode root,int k,int count){//returns result[]2 array containing count in rval[0] and desired element in rval[1] position.
    if(root==null){
        int[]  i=new int[2];
        i[0]=-1;
        i[1]=-1;
        return i;
    }else{
        int rval[]=new int[2];
        int temp[]=new int[2];
        rval=findKthSmallest(root.leftChild,k,count);
        if(rval[0]!=-1){
            count=rval[0];
        }
        count++;
        if(count==k){
            rval[1]=root.data;
        }
        temp=findKthSmallest(root.rightChild,k,(count));
        if(temp[0]!=-1){
            count=temp[0];
        }
        if(temp[1]!=-1){
            rval[1]=temp[1];
        }
        rval[0]=count;
        return rval;
    }
}
public static void main(String args[]){
    BinarySearchTree bst=new BinarySearchTree();
    bst.insert(6);
    bst.insert(8);
    bst.insert(7);
    bst.insert(4);
    bst.insert(3);
    bst.insert(4);
    bst.insert(1);
    bst.insert(12);
    bst.insert(18);
    bst.insert(15);
    bst.insert(16);
    bst.inOrderTraversal();
    System.out.println();
    System.out.println(findKthSmallest(bst.root,11));
}

}


0

यहाँ जावा कोड है,

अधिकतम (नोड रूट, इंट कश्मीर) - kth को सबसे बड़ा खोजने के लिए

मिनट (नोड रूट, इंट कश्मीर) - केथ स्मॉलेस्ट खोजने के लिए

static int count(Node root){
    if(root == null)
        return 0;
    else
        return count(root.left) + count(root.right) +1;
}
static int max(Node root, int k) {
    if(root == null)
        return -1;
    int right= count(root.right);

    if(k == right+1)
        return root.data;
    else if(right < k)
        return max(root.left, k-right-1);
    else return max(root.right, k);
}

static int min(Node root, int k) {
    if (root==null)
        return -1;

    int left= count(root.left);
    if(k == left+1)
        return root.data;
    else if (left < k)
        return min(root.right, k-left-1);
    else
        return min(root.left, k);
}

0

यह भी काम करेगा। बस पेड़ में maxNode के साथ समारोह कहते हैं

def k_largest (सेल्फ, नोड, k): यदि k <0: return कोई नहीं
तो k == 0: रिटर्न नोड और: k - = 1 वापसी self.k_largest (self.predoubor (नोड), k)


0

मुझे लगता है कि यह स्वीकृत उत्तर से बेहतर है क्योंकि इसे बच्चों के नोड्स की संख्या को संग्रहीत करने के लिए मूल ट्री नोड को संशोधित करने की आवश्यकता नहीं है।

हमें बस क्रम में उपयोग करने की आवश्यकता है कि बाएं से दाएं तक के सबसे छोटे नोड को गिनने के लिए, के।

private static int count = 0;
public static void printKthSmallestNode(Node node, int k){
    if(node == null){
        return;
    }

    if( node.getLeftNode() != null ){
        printKthSmallestNode(node.getLeftNode(), k);
    }

    count ++ ;
    if(count <= k )
        System.out.println(node.getValue() + ", count=" + count + ", k=" + k);

    if(count < k  && node.getRightNode() != null)
        printKthSmallestNode(node.getRightNode(), k);
}

0

सबसे अच्छा दृष्टिकोण पहले से ही है। लेकिन मैं उसके लिए एक सरल कोड जोड़ना चाहूंगा

int kthsmallest(treenode *q,int k){
int n = size(q->left) + 1;
if(n==k){
    return q->val;
}
if(n > k){
    return kthsmallest(q->left,k);
}
if(n < k){
    return kthsmallest(q->right,k - n);
}

}

int size(treenode *q){
if(q==NULL){
    return 0;
}
else{
    return ( size(q->left) + size(q->right) + 1 );
}}

0

नोड पाया जाता है और वर्तमान कश्मीर को ट्रैक करने के लिए सहायक परिणाम वर्ग का उपयोग करना।

public class KthSmallestElementWithAux {

public int kthsmallest(TreeNode a, int k) {
    TreeNode ans = kthsmallestRec(a, k).node;
    if (ans != null) {
        return ans.val;
    } else {
        return -1;
    }
}

private Result kthsmallestRec(TreeNode a, int k) {
    //Leaf node, do nothing and return
    if (a == null) {
        return new Result(k, null);
    }

    //Search left first
    Result leftSearch = kthsmallestRec(a.left, k);

    //We are done, no need to check right.
    if (leftSearch.node != null) {
        return leftSearch;
    }

    //Consider number of nodes found to the left
    k = leftSearch.k;

    //Check if current root is the solution before going right
    k--;
    if (k == 0) {
        return new Result(k - 1, a);
    }

    //Check right
    Result rightBalanced = kthsmallestRec(a.right, k);

    //Consider all nodes found to the right
    k = rightBalanced.k;

    if (rightBalanced.node != null) {
        return rightBalanced;
    }

    //No node found, recursion will continue at the higher level
    return new Result(k, null);

}

private class Result {
    private final int k;
    private final TreeNode node;

    Result(int max, TreeNode node) {
        this.k = max;
        this.node = node;
    }
}
}

0

पायथन समाधान समय जटिलता: O (n) अंतरिक्ष जटिलता: O (1)

आइडिया को मॉरिस इनवर्टर ट्रैवर्सल का उपयोग करना है

class Solution(object):
def inorderTraversal(self, current , k ):
    while(current is not None):    #This Means we have reached Right Most Node i.e end of LDR traversal

        if(current.left is not None):  #If Left Exists traverse Left First
            pre = current.left   #Goal is to find the node which will be just before the current node i.e predecessor of current node, let's say current is D in LDR goal is to find L here
            while(pre.right is not None and pre.right != current ): #Find predecesor here
                pre = pre.right
            if(pre.right is None):  #In this case predecessor is found , now link this predecessor to current so that there is a path and current is not lost
                pre.right = current
                current = current.left
            else:                   #This means we have traverse all nodes left to current so in LDR traversal of L is done
                k -= 1
                if(k == 0):
                    return current.val
                pre.right = None       #Remove the link tree restored to original here 
                current = current.right
        else:               #In LDR  LD traversal is done move to R 
            k -= 1
            if(k == 0):
                return current.val
            current = current.right

    return 0

def kthSmallest(self, root, k):
    return self.inorderTraversal( root , k  )

-1

मैंने kth सबसे छोटे तत्व की गणना करने के लिए एक साफ फ़ंक्शन लिखा है। मैं इन-ऑर्डर ट्रैवर्सल का उपयोग करता हूं और जब यह kth सबसे छोटे तत्व तक पहुंचता है तो रुक जाता है।

void btree::kthSmallest(node* temp, int& k){
if( temp!= NULL)   {
 kthSmallest(temp->left,k);       
 if(k >0)
 {
     if(k==1)
    {
      cout<<temp->value<<endl;
      return;
    }

    k--;
 }

 kthSmallest(temp->right,k);  }}

कोई मेट्रिक्स उपलब्ध नहीं है कि यह क्यों इष्टतम है। दोनों बड़े और छोटे मामलों में
Woot4Moo

-1
int RecPrintKSmallest(Node_ptr head,int k){
  if(head!=NULL){
    k=RecPrintKSmallest(head->left,k);
    if(k>0){
      printf("%c ",head->Node_key.key);
      k--;
    }
    k=RecPrintKSmallest(head->right,k);
  }
  return k;
}

2
कृपया विवरण के कुछ स्तर के साथ हमेशा कोड के साथ करें कि यह क्या करता है और यह समस्या को हल करने में कैसे मदद करता है।
रेन

-1
public TreeNode findKthElement(TreeNode root, int k){
    if((k==numberElement(root.left)+1)){
        return root;
    }
    else if(k>numberElement(root.left)+1){
        findKthElement(root.right,k-numberElement(root.left)-1);
    }
    else{
        findKthElement(root.left, k);
    }
}

public int numberElement(TreeNode node){
    if(node==null){
        return 0;
    }
    else{
        return numberElement(node.left) + numberElement(node.right) + 1;
    }
}

-1
public static Node kth(Node n, int k){
    Stack<Node> s=new Stack<Node>();
    int countPopped=0;
    while(!s.isEmpty()||n!=null){
      if(n!=null){
        s.push(n);
        n=n.left;
      }else{
        node=s.pop();
        countPopped++;
        if(countPopped==k){
            return node;
        }
        node=node.right;

      }
  }

}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.