Optimum উপায়ে বাইনারি অনুসন্ধান গাছে kth ক্ষুদ্রতম উপাদান সন্ধান করুন


112

আমার কোনও স্থিতিশীল / গ্লোবাল ভেরিয়েবল ব্যবহার না করে বাইনারি অনুসন্ধান গাছে kth ক্ষুদ্রতম উপাদান খুঁজে পাওয়া দরকার। কীভাবে দক্ষতার সাথে এটি অর্জন করবেন? আমার মনে যে সমাধানটি রয়েছে তা হ'ল ও (এন) এ অপারেশন করছে, যেহেতু আমি পুরো গাছটির অভ্যন্তরীণ ট্র্যাভারসাল করার পরিকল্পনা করছি বলে সবচেয়ে খারাপ এটি। তবে গভীরভাবে অনুভব করছি যে আমি এখানে বিএসটি সম্পত্তি ব্যবহার করছি না। আমার অনুমানমূলক সমাধানটি কি সঠিক বা আরও ভাল কোনও উপলভ্য?


7
গাছ কি ভারসাম্যহীন?
কেনেটিএম

এটা না। তবে যদি এটি ভারসাম্যপূর্ণ হয়, তবে কি কোনও সর্বোত্তম উপায় আছে?
বড়াইবাবু

1
আপনি যদি "অর্ডার পরিসংখ্যান" অনুসন্ধান করেন তবে আপনার যা প্রয়োজন তা তা পেয়ে যাবেন।
রাল

আমি নীচের উত্তরগুলির বেশিরভাগ বোধ করি, যখন সঠিকভাবে প্রতারণা করা হয় যে তারা কোনও ধরণের বিশ্বব্যাপী ভেরিয়েবল ব্যবহার করছে (এটি কোনও পূর্ণসংখ্যার রেফারেন্স হোক না কেন, এবং একটি পরিবর্তনশীল যা হ্রাস পেয়ে ফিরে আসবে)। যদি একে অপরকে অনুমতি না দেওয়া হয় তবে আমি কোনও উল্লেখ ছাড়াই পুনরাবৃত্তি ব্যবহার করব
হেনলি চিউ

উত্তর:


170

এখানে ধারণার একটি রূপরেখা:

একটি বিএসটি- Tতে নোডের বাম সাবট্রিতে কেবলমাত্র সঞ্চিত মানের চেয়ে ছোট উপাদান থাকে T। যদি kবাম সাবট্রির উপাদানগুলির সংখ্যার চেয়ে ছোট হয় তবে ত্রয়োতমতম kক্ষুদ্রতম উপাদান অবশ্যই বাম সাবট্রির অন্তর্গত। অন্যথায়, যদি kবড় হয় তবে kত্রয়োতমতম ক্ষুদ্রতম উপাদানটি ডান সাবট্রিতে থাকে in

আমরা প্রতিটি নোডকে তার বাম সাবট্রিতে উপাদানগুলির সংখ্যা সঞ্চয় করতে বিএসটি বৃদ্ধি করতে পারি (ধরে নিও যে প্রদত্ত নোডের বাম সাবট্রিতে সেই নোড রয়েছে)। এই টুকরো তথ্যের সাহায্যে, বাম সাবট্রিতে উপাদানগুলির সংখ্যা বারবার জিজ্ঞাসা করে, বামে বা ডান সাবট্রিতে পুনরাবৃত্তি করতে হবে কিনা তা সিদ্ধান্ত নিয়ে গাছটি অতিক্রম করা সহজ।

এখন, ধরুন আমরা নোড টি তে রয়েছি:

  1. যদি k == num_elements (টি এর বাম সাবট্রি) থাকে , তবে আমরা যে উত্তরটি খুঁজছি তা হ'ল নোডের মান T
  2. যদি k> num_elements (টি এর বাম সাবট্রি) থাকে , তবে স্পষ্টতই আমরা বাম সাবট্রিকে উপেক্ষা করতে পারি, কারণ সেই উপাদানগুলিও ত্রৈতমতমের চেয়ে kছোট হবে। সুতরাং, আমরা k - num_elements(left subtree of T)ডান সাবট্রির ক্ষুদ্রতম উপাদান সন্ধান করতে সমস্যা হ্রাস করি ।
  3. যদি কে <নাম_ এলিমেন্টস (টি এর বাম সাবট্রি) থাকে , তবে তমতমতমতম বাম সাবট্রিরk কোথাও থাকে, তাই আমরা বাম সাবট্রির মধ্যে তমতমk ক্ষুদ্রতম উপাদানটি খুঁজে পেতে সমস্যা হ্রাস করি ।

জটিলতা বিশ্লেষণ:

এটি O(depth of node)সময় নেয় , যা O(log n)ভারসাম্যপূর্ণ বিএসটি-র সবচেয়ে খারাপ ক্ষেত্রে বা O(log n)গড় এলোমেলোভাবে বিএসটি-র জন্য।

একটি বিএসটি-র O(n)স্টোরেজ প্রয়োজন এবং O(n)উপাদানগুলির সংখ্যা সম্পর্কিত তথ্য সংরক্ষণ করতে এটি অন্য লাগে । সমস্ত বিএসটি অপারেশনগুলিতে O(depth of node)সময় লাগে এবং O(depth of node)নোডগুলি সন্নিবেশ, মোছা বা ঘোরানোর জন্য "উপাদানগুলির সংখ্যা" তথ্য বজায় রাখতে অতিরিক্ত সময় লাগে । সুতরাং, বাম সাবট্রিতে উপাদানগুলির সংখ্যা সম্পর্কে তথ্য সংরক্ষণ করা একটি বিএসটির স্থান এবং সময় জটিলতা বজায় রাখে।


59
নবমতম আইটেমটি সন্ধান করতে আপনার কেবল বাম উপ-গাছের আকার সংরক্ষণ করতে হবে। আপনি যদি সঠিক উপ-গাছের আকারটি ব্যবহার করেন তবে আপনি যদি এনথের বৃহত্তম আইটেমটি সন্ধান করতে সক্ষম হন। প্রকৃতপক্ষে, আপনি এটিকে কম ব্যয় করতে পারেন: গাছের মোট আকার এবং শিকড়ের বাম উপ-গাছের আকার সংরক্ষণ করুন। যখন আপনার ডান উপ-গাছের আকার প্রয়োজন হয়, আপনি মোট আকার থেকে বামের আকার বিয়োগ করতে পারেন।
জেরি কফিন

37
এ জাতীয় বর্ধিত বিএসটি-কে 'অর্ডার পরিসংখ্যান গাছ' বলা হয়।
ড্যানিয়েল

10
@ আইভ্ল্যাড: দ্বিতীয় ধাপে: আমি মনে করি যে "কে - নাম_ উপাদানগুলি" "কে - নাম_ উপাদানসমূহ -1" হওয়া উচিত, যেহেতু আপনিও মূল উপাদানটি অন্তর্ভুক্ত করেছেন।
understack

1
@ উইন্ডট্যাক - আপনি মূলটিকে সাবট্রির অংশ হিসাবে ধরে নিলে তা নয়।
আইভ্ল্যাড

16
যদি গাছটিতে "তার বাম এবং ডান সাবট্রির উপাদানগুলির সংখ্যা" সম্বলিত ক্ষেত্র না থাকে তবে পদ্ধতিটি বিগও (এন) হিসাবে শেষ হবে কারণ আপনাকে প্রতিটি নোডে ডান বা বাম সাবট্রিকে চলতে হবে বর্তমান নোডের কে সূচক গণনা করুন।
রবার্ট এস বার্নেস

68

একটি সহজ সমাধান হ'ল একটি অভ্যন্তরীণ ট্র্যাভারসাল করা এবং বর্তমানে মুদ্রণযোগ্য উপাদানটির সন্ধান করা (এটি প্রিন্ট না করে)। যখন আমরা কে পৌঁছে যাব, উপাদানটি মুদ্রণ করুন এবং গাছের ট্র্যাভারসাল বাকি রেখে যান।

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: ধারণাটি সঠিক দিকে রয়েছে তবে কিছু আলগা প্রান্তটি আরও কড়া করা দরকার; দেখুন স্ট্যাকওভারফ্লো.com
অরুণ

1
আমি এই সমাধানটি পছন্দ করি, যেহেতু বিএসটি ইতিমধ্যে অর্ডার করা হয়েছে, ট্র্যাভারসাল যথেষ্ট হওয়া উচিত।
মের্লিন

3
N এই গাছের মোট নোডের কাছাকাছি থাকলে আপনার অ্যালগরিদমটি শেষ করতে ও (এন) সময় লাগবে যা নির্বাচিত উত্তর-ও (লগ এন) এর জন্য খারাপ
স্পার্ক 8006

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

এটি সি # তে আমার বাস্তবায়ন উপরের অ্যালগরিদমের উপর ভিত্তি করে কেবল ভেবেছিল আমি এটি পোস্ট করেছি যাতে লোকেরা আরও বুঝতে পারে যে এটি আমার পক্ষে কাজ করে

ধন্যবাদ আইভ্ল্যাড


11

একটি সহজ সমাধান হ'ল একটি অভ্যন্তরীণ ট্র্যাভারসাল করা এবং বর্তমানে কাউন্টার কে দিয়ে মুদ্রিত হওয়া উপাদানটির উপর নজর রাখা। যখন আমরা কে পৌঁছেছি, উপাদান মুদ্রণ। রানটাইম হল ও (এন)। ফাংশন রিটার্ন প্রকারটি বাতিল হওয়া যাবে না মনে রাখবেন, প্রতিটি পুনরাবৃত্তির কল করার পরে এটির কে এর আপডেট হওয়া মানটি ফিরিয়ে দিতে হবে। এর আরও ভাল সমাধান হ'ল প্রতিটি নোডে বাছাই করা পজিশনের মান সহ একটি বর্ধিত বিএসটি।

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

আমি এই সমাধানটি এবং সংশ্লিষ্ট পুনরাবৃত্তিকে পছন্দ করি। সত্যই, এই প্রশ্নের বেশিরভাগ উত্তর খুব বিভ্রান্তিকর / জটিল।
হেনলি চিউ

আমি এই সমাধান ভালোবাসি! পরিষ্কার এবং দুর্দান্ত!
রুগাল

এই সমাধানটি গাছটিকে 'ইন-অর্ডার' হিসাবে অনুসরণ করছে এবং নোডটি দেখার পরে একটি কাউন্টার হ্রাস করছে, পরে যখন কাউন্টারটি শূন্যের সমান হয় তখন থামবে। সবচেয়ে খারাপ অবস্থা হ'ল অর্ডার ও (এন) এর। @ আইভ্ল্যাডের পুনরাবৃত্ত সমাধানগুলির সাথে তুলনা করা সবচেয়ে অনুকূল নয় যার সবচেয়ে খারাপ ক্ষেত্রে ও (লগ এন) লাগে
জর্জি পি

7

আপনি পুনরাবৃত্তি ইনঅর্ডার ট্র্যাভারসাল ব্যবহার করতে পারেন: http://en.wikedia.org/wiki/Tree_traversal# স্ট্যাকের বাইরে একটি নোড পপ করার পরে kth এলিমেন্টের জন্য একটি সাধারণ চেক দিয়ে _T


4

কেবল একটি সরল বাইনারি অনুসন্ধান গাছ দেওয়া, আপনি যা করতে পারেন তার সব থেকে ছোট থেকে শুরু হয় এবং ডান নোডটি সন্ধান করতে উপরের দিকে যেতে হবে।

যদি আপনি এটি খুব ঘন ঘন করতে চলেছেন তবে আপনি প্রতিটি নোডের একটি বৈশিষ্ট্য যুক্ত করতে পারেন যা তার বাম উপ-গাছে কয়টি নোড রয়েছে তা নির্দেশ করে। এটি ব্যবহার করে আপনি গাছটি সরাসরি সঠিক নোডে নামতে পারেন।


4

পুনরাবৃত্তিমূলক ইন-অর্ডার একটি কাউন্টার সহ হাঁটুন

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

ধারণাটি @ প্রসাদভক সমাধানের মতো, তবে এতে কিছু ত্রুটি রয়েছে (নীচে নোট দেখুন), তাই আমি এটি আলাদা উত্তর হিসাবে পোস্ট করছি।

// 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তবে এটি এই প্রশ্নের জন্য অবৈধ।
ভ্যালেন্টিন শার্গিন

হাই অরুণ, আপনি দয়া করে একটি উদাহরণ দিয়ে ব্যাখ্যা করতে পারেন? আমি আপনার বিশেষত এটি প্রথম বুঝতে পারি না।
অ্যান্ডি 897

3

জন্য না গাছ অনুসন্ধানের সুষম লাগে হে (ঢ)

জন্য সুষম অনুসন্ধানের গাছ, এটা লাগে হে (ট + + লগ ঢ) সবচেয়ে খারাপ ক্ষেত্রে কিন্তু হে (ট) মধ্যে amortized অর্থে।

প্রতিটি নোডের জন্য অতিরিক্ত পূর্ণসংখ্যা থাকা এবং পরিচালনা করা: উপ-গাছের আকার ও (লগ এন) সময় জটিলতা দেয়। এই জাতীয় ভারসাম্যযুক্ত অনুসন্ধান গাছকে সাধারণত র্যাঙ্কট্রি বলা হয়।

সাধারণভাবে, সমাধান রয়েছে (গাছের ভিত্তিতে নয়)।

শুভেচ্ছা।


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
আমি মনে করি না এই সমাধানটি কার্যকর হবে। কেথের ক্ষুদ্রতমটি যদি গাছের নোডের ডান সাব গাছে থাকে?
অনিল বিশ্বনাই

0

ওয়েল, আমরা কেবল ক্রম ক্রমটিকে ট্র্যাভারসাল ব্যবহার করতে এবং পরিদর্শন করা উপাদানটিকে একটি স্ট্যাকের দিকে ঠেলাতে পারি। উত্তর পেতে বার বার পপ কে।

আমরা কে উপাদানগুলির পরেও থামতে পারি


1
এটি কোনও সর্বোত্তম সমাধান নয়
ব্রেগবয়

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

লিনাক্স কার্নেলের একটি দুর্দান্ত বর্ধিত লাল-কালো গাছের ডেটা কাঠামো রয়েছে যা লিনাক্স / লিব / আরবিটি্রি.সি তে ও (লগ এন) এ র‌্যাঙ্ক-ভিত্তিক ক্রিয়াকলাপ সমর্থন করে।

একটি খুব অশোধিত জাভা বন্দরটি 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 (আরবিএন নোড, ইন্ট এন) কল করে গাছের গোড়ায় গিয়ে can


0

এখানে একটি সংক্ষিপ্ত সংস্করণ C # এর যে আয় 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

http://www.geeksforgeeks.org/archives/10379

এটি এই প্রশ্নের সঠিক উত্তর: -

1. ও (এন) সময়ে ইনঅর্ডার ট্র্যাভার্সাল ব্যবহার করে ২. কে + লগ এন সময়ে আগুনযুক্ত গাছ ব্যবহার করা using


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

এখানে জাভা কোড,

সর্বাধিক (নোড রুট, ইন্ট কে) - কেথ বৃহত্তম সন্ধান করতে

মিনিট (নোড রুট, ইন্ট কে) - কেথ সবচেয়ে ক্ষুদ্রতম সন্ধান করতে

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

এটি খুব কাজ করবে। কেবলমাত্র গাছটিতে ম্যাক্সনোড দিয়ে ফাংশনটি কল করুন

ডিএফ কে_লার্জস্ট (স্ব, নোড, কে): কে <0: রিটার্ন কেউ নেই
তবে কে == 0: রিটার্ন নোড অন্য: কে - = 1 রিটার্ন সেল্ট.কে_লাজেস্ট (স্ব.প্রেডেসর (নোড), কে)


0

আমি মনে করি এটি গৃহীত উত্তরের চেয়ে উত্তম কারণ এটি শিশু নোডের সংখ্যা সংরক্ষণের জন্য মূল গাছ নোডটি সংশোধন করার দরকার নেই।

বাম থেকে ডানে ছোট নোড গণনা করতে আমাদের কেবল ইন-অর্ডার ট্রভারসাল ব্যবহার করা দরকার, একবার গণনা কে এর সমান হলে অনুসন্ধান বন্ধ করুন stop

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

পাইথন সলিউশন সময় জটিলতা: ও (এন) স্পেস জটিলতা: ও (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 ক্ষুদ্রতম উপাদান গণনা করার জন্য একটি ঝরঝরে ফাংশন লিখেছি। আমি ক্রম ট্র্যাভারসাল ব্যবহার করি এবং যখন এটি কাঁথের ক্ষুদ্রতম এলিমেন্টে পৌঁছে যায় তখন থামে।

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;

      }
  }

}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.