nth smallest element of a BST - algorithm

a BST(binary search tree) T is given.
how to find the nth smallest element of T ?

A binary search tree is effectively sorted, so you just need to go through the tree in-order and get to the nth spot. If the tree is fully balanced, you can calculate the spot to get to.

If the binary search tree is not fully balanced, then you need to do a recursive search to find the nth smallest element. This can be hugely accelerated by having each node store the number of subnodes pointed to by each of its branch pointers, effectively turning the search into a binary one. However, this add overhead on tree updates as each insertion or deletion now requires a leaf-to-root traversal to update the node counts.
Alternatively, you can keep the tree balanced, and use the above answer.

Related

runtime to find middle element using AVL tree

I have an one lecture slides says following:
To find middle element in AVL tree, I traverse elements in order until It reaches the moddile element. It takes O(N).
If I know correctly, in tree structure, finding element takes base 2 O(logn) since AVL is binary tree that always divided into 2 childs.
But why it says O(N)?
I am just trying to elaborate 'A. Mashreghi' comment.
Since, the tree under consideration is AVL tree - the guaranteed finding of element in O(log n) holds as log as you have the element(key) to find.
The problem is - you are trying to identify a middle element in the given data structure. As it is AVL tree (self balanced BST) in-order travel gives you elements in ascending order. You want to use this property to find the middle element.
Algorithm goes like - have a counter increment for every node traversed in-order and return # n/2th position. This sums to O(n/2) and hence the overall complexity O(n).
Being divided into 2 children does not guarantee perfect symmetry. For instance, consider the most unbalanced of all balanced binary trees: each right child has a depth one more than its corresponding left child.
In such a tree, the middle element will be somewhere down in the right branch's left branch's ...
You need to determine how many nodes N you have, then locate the N/2th largest node. This is not O(log N) process.

Level in binary tree with most nodes

What is the minimal amount of space needed to find out which level in binary tree (random or BST) has the most number of nodes?
If you are allowed to destroy the tree, then you can convert the tree to a linked list while doing a bfs of the tree, essentially simulating a queue with the tree itself!
You can find information about that here: Convert a binary tree to linked list, breadth first, constant storage/destructive
This requires only O(1) space as you have reused the nodes of the tree.
O(1)
Traverse the BT (Binary Tree) in Breadth-First-Search approach. Push nodes with mentioning the level of it. You will traverse all nodes in a level and then go to the next level. So just maintain the a maximum variable and keep updating it.
The Queue(for BST) could take space in O(2^(log(n) -1)).

Pseudocode for non-recursive implementation of tree height and isBST

I am in the process of converting recursive function for a BST to non recursive to help prepare for an interview. So far I figured out preorder, inorder, postorder, search, delete, insert, and converting the BST to a circular linked list. I am having trouble figuring out how to use stack or queues to get the height and to find if it is a BST. Any tips would be greatly appreciated. I am not looking for code but the logic behind the code.
For starters, great job preparing for interviews like this! I hope that you're having fun playing around with these algorithms.
Let's begin with the task of trying to determine if the binary tree is a BST. One way of doing this is to do an inorder walk of the tree and check if the elements are in sorted order. This will be true if and only if the tree is a BST. Since you already have code to do an inorder walk of the elements of the tree, you should be able to easily adapt your code to check if the elements that come out of the inorder walk are sorted by keeping track of the last element you saw in the inorder walk, then comparing each element generated to the previous element. If the two are out of order, the tree is not a BST.
To determine the height of the tree, one option would be to take any of the searches that you've come up with so far (preorder, postorder, inorder) and keep track of the height of the stack at each point. The idea here is that since your stack will always keep track of the path back from any node up to the root, you can simply walk the tree and record the deepest that you ever saw the stack become. This maximum depth is then the height of the tree.
Hope this helps! And best of luck with interviews!
To find the height of the tree, you could use the Morris traversal [ O(n) time]].
To check if it is a valid BST, do an inorder walk of the tree.
Move the elements into an array. Check if the array is sorted or not to validate a BST.

Binary tree to Binary Search Tree (BST)

How can you convert Binary Tree to Binary Search Tree with O(1) extra space ?
Converting an unordered binary tree into an ordered binary search tree is trivial, but a bit more difficult to do fast.
Here's a naive implementation that should satisfy your criteria, I will not describe the actual steps to take, just the overall algorithm.
Grab a random leaf node from your existing tree
Unlink the leaf node from your existing tree
Make the node the root of your new binary search tree
Grab another random leaf node from your existing tree
Unlink that node from your existing tree
Find the right spot for, and link the node, into your new binary search tree
Repeat step 4-6 until the original tree is empty
You should require only a few variables, like the parent of the leaf node you're unlinking (unless the nodes has parent-links), the root node of the new tree, and a couple of temporary variables, all within your O(1) space criteria.
This will not produce an optimal binary search tree. For that you need to either sort the nodes before adding them, and adding them in the right order, or use a balancing binary search tree, like a red-black tree or a splay tree.
Convert Binary Tree to a doubly linked list- can be done inplace in O(n)
Then sort it using merge sort, nlogn
Convert the list back to a tree - O(n)
Simple nlogn solution.

How can I efficiently get to the leaves of a binary-search tree?

I want to sum all the values in the leaves of a BST. Apparently, I can't get to the leaves without traversing the whole tree. Is this true? Can I get to the leaves without taking O(N) time?
You realize that the leaves themselves will be at least 1/2 of O(n) anyway?
There is no way to get the leaves of a tree without traversing the whole tree (especially if you want every single leaf), which will unfortunately operate in O(n) time. Are you sure that a tree is the best way to store your data if you want to access all of these leaves? There are other data structures which will allow more efficient access to your data.
To access all leaf nodes of a BST, you will have to traverse all the nodes of BST and that would be of order O(n).
One alternative is to use B+ tree where you can traverse to a leaf node in O(log n) time and after that all leaf nodes can be accessed sequentially to compute the sum. So, in your case it would be O(log n + k), where k is the number of leaf nodes and n is the total number of nodes in the B+ tree.
cheers
You will either have to traverse the tree searching for nodes without children, or modify the structure you are using to represent the tree to include a list of the leaf nodes. This will also necessitate modifying your insert and delete methods to maintain the list (for instance, if you remove the last child from a node, it becomes a leaf node). Unless the tree is very large, it's probably nice enough to just go ahead and traverse the tree.

Resources