views:

1299

answers:

4

How to find the Nth largest node in a BST?

Do I keep a count variable while doing In Order Traversal of a BST? Return the element when the count = N???

+2  A: 

Hint: use inorder traversal of the tree. It can print out the items in sorted order, so you can sure find the Nth largest item. Keep a counter as you "walk", incrementing each time you "visit" a node.

Edit: while IVlad's answer is indeed faster, it requires you to keep extra information in the nodes. This answer doesn't but it's O(n). Just pointing out that this is a tradeoff you have to be aware of.

Eli Bendersky
This works, but it's not optimal. There's a much better way.
IVlad
@IVlad: doesn't your method require extra storage in the BST nodes?
Eli Bendersky
Not more than yours does. How are you going to traverse the tree without extra storage? The recursion stack also counts as extra memory.
IVlad
@IVlad: this is not the point. The point is modifying the BST nodes to hold extra information for the traversal
Eli Bendersky
Yes, so? What's the disadvantage in doing that?
IVlad
@IVlad: depends on the context, but it's usually something that has to be allowed. The other solution is not optimal in terms of runtime, but it doesn't require this extra storage, so I see no obvious reason for a downvote
Eli Bendersky
Why is it usually "something that has to be allowed"? It uses at most as much memory as this solution and it's faster. I would think using something slower is something that has to be allowed. The downvote was because this isn't optimal and, more importantly, because it's the exact same solution the OP had in mind, so you could've just said "yes" in a comment. Your downvote however truly makes no sense, and it's kind of sad to see coming from someone with 20k reputation.
IVlad
@IVlad: because this is a homework question, not designing a production algorithm. This is why there are rules. I tried to revoke my downvote but it was too late, you'll have to edit the answer for making it possible.
Eli Bendersky
Well in my experience teachers aren't that picky, they'll appreciate a faster solution even if it involves some adjustments to the data structure. I've edited my answer.
IVlad
@IVlad: Our experiences differ, then. downvote revoked
Eli Bendersky
I guess so. Thanks for revoking the vote, I've done the same.
IVlad
IVlad: Your solution requires O(n) extra storage: a count in every node. This solution requires only O(log n) extra storage, for the maximum depth of the stack used in recursion.
jemfinch
@jemfinch: yes, my solution requires O(n) extra storage all the time. This one requires O(log n) on average, but can also be O(n) if the tree isn't balanced.
IVlad
+4  A: 

See my answer here. You can do this in O(log n) on average where n = number of nodes. Worst case is still O(n) IF the tree isn't balanced (always O(log n) if it is balanced however). In order traversal is always O(n) however.

IVlad
Of course, that only works if you can modify the nodes of your binary tree. If you're using a library binary tree, your solution isn't an option.
jemfinch
I think that filling the tree with the required additional information costs O(n), doesn't it? So if the given tree is without the additional information, i don't see how it can be solved in O(log n).
duduamar
It requires O(n) memory, but not any additional time, only the time required to construct the tree in memory.
IVlad
A: 

Use a inverted inorder tranversal.that is go to right child first instead of left child. recursively this can be obtained as follows: The most important issue that a global count must be used when considering recursive solution.

reverseInorder(root){
 if(root!=null){
reverseInorder(root->rightChild);
self
reverseInorder(root->leftChild);
}
}

Solution in java

    package datastructure.binaryTree;

import datastructure.nodes.BinaryTreeNode;


public class NthElementFromEnd {
    private BinaryTree tree=null;
    int currCount=0;
    public NthElementFromEnd(int[] dataArray) {
        this.tree=new BinaryTree(dataArray);

    }
    private void getElementFromEnd(int n){
        getElementFromEnd(this.tree.getRoot(),n);
    }
    private void getElementFromEnd(BinaryTreeNode node,int n){
        if(node!=null){
            if(currCount<n)
            getElementFromEnd(node.getRightChild(),n);
            currCount++;

            if(currCount==n)
            {
                System.out.print(" "+node.getData());
                return;
            }
            if(currCount<n)
            getElementFromEnd(node.getLeftChild(),n);
        }
    }

    public static void main(String args[]){
        int data[]={1,2,3,4,5,6,7,8,9};
        int n=2;
        new NthElementFromEnd(data).getElementFromEnd(n);
    }
}
frictionlesspulley
A: 

the above worked...

puneet