Traversing two paths of a binary search tree and nulling the one where target isn't found (Java) - binary-tree

public String searchTreeNode(Character target, TreeNode current, String result) {
Character left = current.getLeft().getData().getCharacter();
Character right = current.getRight().getData().getCharacter();
//Both children are characters
if(left != null && right != null){
//found at right
if(right == target){
result += "1";
}
//found at left
else if (left == target){
result += "0";
}
}
//left is a character and right is a null
else if(left != null && right == null){
//found at left
if(left == target){
result += "0";
}
//move to right node
else{
result = searchTreeNode(target, current.getRight(), "1" + result);
}
}
//right is a character and left is a null
else if(right != null && left == null){
//found at right
if(right == target){
result += "1";
}
//move to left node
else{
result = searchTreeNode(target, current.getLeft(), "0" + result);
}
}
//if both children are null
else if (right == null && left == null){
result = searchTreeNode(target, current.getLeft(), result) + searchTreeNode(target, current.getRight(), result);
}
else{
result = "";
}
return result;
}
In a Huffman root tree it is easy to know which direction to go if one is null and another is a character since you either find the character, or go down the null child. However if both children are null, I cannot figure out how to null the side that doesn't find the child since I traverse both. Is there a way to null the side that doesn't result in finding the target?
When I traversed both sides, I would add up both sides that would recursively go through the function until it found the target or ended up null within the else statement. However since it has already "traversed" with recursion I cannot null the already added bit strings. So instead of only printing the path towards the target only it print both sides.

Related

To print the boundary of Binary Tree

I have been asked in an interviews to print the boundary of the Binary Tree. For example.
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ \
8 9 10
Answer will be : 1, 2, 4, 8, 9, 10, 7, 3
I have given the following answer.
First Method :
I have used a Bool variable to solve the above problem.
void printLeftEdges(BinaryTree *p, bool print) {
if (!p) return;
if (print || (!p->left && !p->right))
cout << p->data << " ";
printLeftEdges(p->left, print);
printLeftEdges(p->right, false);
}
void printRightEdges(BinaryTree *p, bool print) {
if (!p) return;
printRightEdges(p->left, false);
printRightEdges(p->right, print);
if (print || (!p->left && !p->right))
cout << p->data << " ";
}
void printOuterEdges(BinaryTree *root) {
if (!root) return;
cout << root->data << " ";
printLeftEdges(root->left, true);
printRightEdges(root->right, true);
}
His Response : You have used Bool variable so many times. Can you solve this without using that.
Second Method :
I simply used tree traversal to solve this problem.
1. Print the left boundary in top-down manner.
2. Print all leaf nodes from left to right, which can again be sub-divided into two sub-parts:
2.1 Print all leaf nodes of left sub-tree from left to right.
2.2 Print all leaf nodes of right subtree from left to right.
3. Print the right boundary in bottom-up manner.
His Response : He was not happy with this method too. He told that you are traversing the tree 3 times. That is too much. Give another solution if you have any.
Third Method :
This time i have went for Level Order traversal (BFS).
1: Print starting and ending node of each level
2: For each other node check if its both the children are <b>NULL</b> then print that node too.
His Response : He was not seems happy with this method too because this method takes extra memory of order O(n).
My question is that Tell me a method which traverse tree single times, do not use any Bool variable and do not use any extra memory. Is it possible?
I guess this should do the trick:
traverse(BinaryTree *root)
{
if (!root) return;
cout << p->data << " ";
if (root->left ) traverseL(root->left ); //special function for outer left
if (root->right) traverseR(root->right); //special function for outer right
}
traverseL(BinaryTree *p)
{
cout << p->data << " ";
if (root->left ) traverseL(root->left ); //still in outer left
if (root->right) traverseC(root->right);
}
traverseR(BinaryTree *p)
{
if (root->left ) traverseC(root->left );
if (root->right) traverseR(root->right); //still in outer right
cout << p->data << " ";
}
traverseC(BinaryTree *p)
{
if (!root->left && !root->right) //bottom reached
cout << p->data << " ";
else
{
if (root->left ) traverseC(root->left );
if (root->right) traverseC(root->right);
}
}
Start with the traverse function.
Got rid of the null-queries at the beginning of each method (avoids one function call at each end).
Does not need bool variables, simply uses three different traversal methods:
one for the left edge, outputting the node before traversal
one for the right edge, outputting the node after traversal
one for all other nodes, outputting the node if there are no siblings.
Below is a recursive solution in Python3 with time complexity O(n). Algorithm here is to print left most nodes from top to bottom, leaf nodes from left to right and right most nodes from bottom to top. Adding boolean flags (isLeft,isRight) for left and right tree traversal simplifies the code and drives the time complexity of O(n).
#Print tree boundary nodes
def TreeBoundry(node,isLeft,isRight):
#Left most node and leaf nodes
if(isLeft or isLeaf(node)): print(node.data,end=' ')
#Process next left node
if(node.getLeft() is not None): TreeBoundry(node.getLeft(), True,False)
#Process next right node
if(node.getRight() is not None):TreeBoundry(node.getRight(), False,True)
#Right most node
if(isRight and not isLeft and not isLeaf(node)):print(node.data,end=' ')
#Check is a node is leaf
def isLeaf(node):
if (node.getLeft() is None and node.getRight() is None):
return True
else:
return False
#Get started
#https://github.com/harishvc/challenges/blob/master/binary-tree-edge-nodes.py
TreeBoundry(root,True,True)
Method O(n) No extra space and single traversal of tree.
I divided the Tree Nodes into four types of nodes
Type 1 -> Nodes which form the left boundary(eg 8)
Type 0 -> Nodes which do not form the boundar(eg 12)
Type 3 -> Nodes which form the right boundary(eg 22)
Leaf Nodes(eg 4,10,14)
In my method i am just doing recurrsion method of tree traversal (just modified) where my function is of this form
void recFunc(btNode *temp,int type)
{
//Leaf Nodes
if((temp->left == NULL)&&(temp->right == NULL))
cout << temp->data << " ";
// type -1 Nodes must be printed before their children
else if(type == 1)cout << temp->data << " ";
else {;}
if(type == 3)
{
if(temp->left)recFunc(temp->left,0);
if(temp->right)recFunc(temp->right,3);
//type 3 nodes must be printed after their children
cout << temp->data << " ";
}
else if(type == 1)
{
if(temp->left)recFunc(temp->left,1);
if(temp->right)recFunc(temp->right,0);
}
else if(type == 0)
{
if(temp->left)recFunc(temp->left,0);
if(temp->right)recFunc(temp->right,0);
}
else {;}
}
where i have modofied the
In my recurrsive function Nodes of type 1 must make their left nodes
as type 1 and must be printed before calling their children(if they
exist)
Nodes Of Type 3 must be printed in reverse order .So they must be
printed after call to their children.They must also assign their
right children as Type 3 Nodes
Nodes Of Type 0 must not be printed and they assign their children as
type 0 Nodes
Leaf Nodes must be directly printed only and return
Link to Code
//4 diff list for 4 different part of the solution
1)left border 2)right border 3)leaf in left tree 4)leaf in right tree
public class PRintBinaryTreeBoundary {
ArrayList<TreeNode> leftBorderList=new ArrayList<>();
ArrayList<TreeNode> leftLEafNode=new ArrayList<>();
ArrayList<TreeNode> rightBorderList=new ArrayList<>();
ArrayList<TreeNode> rightLEafNode=new ArrayList<>();
public static void main(String[] args) {
// TODO Auto-generated method stub
/* 1
/ \
2 3
/ \ / \
4 5 6 7
/ \ \
8 9 10*/
TreeNode one=new TreeNode(1);
TreeNode two=new TreeNode(2);
TreeNode three=new TreeNode(3);
TreeNode four=new TreeNode(4);
TreeNode five=new TreeNode(5);
TreeNode six=new TreeNode(6);
TreeNode seven=new TreeNode(7);
TreeNode eight=new TreeNode(8);
TreeNode nine=new TreeNode(9);
TreeNode ten=new TreeNode(10);
one.left=two; one.right=three;
two.left=four;two.right=five;
three.left=six;three.right=seven;
five.left=eight;
six.right=nine;
seven.right=ten;
PRintBinaryTreeBoundary p=new PRintBinaryTreeBoundary();
p.print(one);
}
private void print(TreeNode one) {
System.out.println(one.val);
populateLeftBorderList(one.left);
populateRightBorderList(one.right);
populateLeafOfLeftTree(one.left);
populateLeafOfRightTree(one.right);
System.out.println(this.leftBorderList);
System.out.println(this.leftLEafNode);
System.out.println(this.rightLEafNode);
Collections.reverse(this.rightBorderList);
System.out.println(this.rightBorderList);
}
private void populateLeftBorderList(TreeNode node) {
TreeNode n = node;
while (n != null) {
this.leftBorderList.add(n);
n = n.left;
}
}
private void populateRightBorderList(TreeNode node) {
TreeNode n = node;
while (n != null) {
this.rightBorderList.add(n);
n = n.right;
}
}
private void populateLeafOfLeftTree(TreeNode leftnode) {
Queue<TreeNode> q = new LinkedList<>();
q.add(leftnode);
while (!q.isEmpty()) {
TreeNode n = q.remove();
if (null == n.left && null == n.right && !this.leftBorderList.contains(n)) {
leftLEafNode.add(n);
}
if (null != n.left)
q.add(n.left);
if (null != n.right)
q.add(n.right);
}
}
private void populateLeafOfRightTree(TreeNode rightNode) {
Queue<TreeNode> q = new LinkedList<>();
q.add(rightNode);
while (!q.isEmpty()) {
TreeNode n = q.remove();
if (null == n.left && null == n.right && !this.rightBorderList.contains(n)) {
rightLEafNode.add(n);
}
if (null != n.left)
q.add(n.left);
if (null != n.right)
q.add(n.right);
}
}
}
Hope this helps:
// Java program to print boundary traversal of binary tree
/* A binary tree node has data, pointer to left child
and a pointer to right child */
class Node {
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree {
Node root;
// A simple function to print leaf nodes of a binary tree
void printLeaves(Node node)
{
if (node != null) {
printLeaves(node.left);
// Print it if it is a leaf node
if (node.left == null && node.right == null)
System.out.print(node.data + " ");
printLeaves(node.right);
}
}
// A function to print all left boundary nodes, except a leaf node.
// Print the nodes in TOP DOWN manner
void printBoundaryLeft(Node node)
{
if (node != null) {
if (node.left != null) {
// to ensure top down order, print the node
// before calling itself for left subtree
System.out.print(node.data + " ");
printBoundaryLeft(node.left);
}
else if (node.right != null) {
System.out.print(node.data + " ");
printBoundaryLeft(node.right);
}
// do nothing if it is a leaf node, this way we avoid
// duplicates in output
}
}
// A function to print all right boundary nodes, except a leaf node
// Print the nodes in BOTTOM UP manner
void printBoundaryRight(Node node)
{
if (node != null) {
if (node.right != null) {
// to ensure bottom up order, first call for right
// subtree, then print this node
printBoundaryRight(node.right);
System.out.print(node.data + " ");
}
else if (node.left != null) {
printBoundaryRight(node.left);
System.out.print(node.data + " ");
}
// do nothing if it is a leaf node, this way we avoid
// duplicates in output
}
}
// A function to do boundary traversal of a given binary tree
void printBoundary(Node node)
{
if (node != null) {
System.out.print(node.data + " ");
// Print the left boundary in top-down manner.
printBoundaryLeft(node.left);
// Print all leaf nodes
printLeaves(node.left);
printLeaves(node.right);
// Print the right boundary in bottom-up manner
printBoundaryRight(node.right);
}
}
// Driver program to test above functions
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
tree.root.right = new Node(22);
tree.root.right.right = new Node(25);
tree.printBoundary(tree.root);
}
}
Boundary Traversal of binary tree
Below is a Java O(n) time complexity solution that solves the problem of counting duplicates (ex: left node that is also leaf node)
class Node {
Node left;
Node right;
int data;
Node(int d) {
data = d;
left = right = null;
}
}
class BinaryTree {
Node root;
public void getBoundary() {
preorderLeft(root);
inorderLeaves(root);
postorderRight(root);
}
public boolean isLeaf(Node node) {
if (node != null && node.left == null && node.right == null) return true;
return false;
}
public void preorderLeft(Node start) {
if (start != null && isLeaf(start) == false) System.out.print(start.data + " ");
if (start.left != null) preorderLeftSide(start.left);
}
public void inorderLeaves(Node start) {
if(start == null) return;
if(start.left != null) inorderLeaves(start.left);
if(start.left == null && start.right == null) System.out.print(start.data + " ");
if(start.right != null) inorderLeaves(start.right);
}
public void postorderRight(Node start) {
if(start.right != null) postorderRightSide(start.right);
if(start != null && isLeaf(start) == false) System.out.print(start.data + " ");
}
}
This YouTube video was very helpful. The author write comments explaining each method and shows how to skip duplicates. https://youtu.be/7GzuxmZ34cI
By using vertical distance from the root node and level we can solve it using list and map.
map<int,int>tmap; #store the vertical distance and level
list<int>llist; #store the node values
void Buildfunction(root,d, l){
if(root == NULL){
return;
} else if(tmap.count(d) == 0){
tmap[d] = l;
llist.push_back(root->data);
} else if((root->left == NULL && root->right==NULL) || tmap[d] < l){
tmap[d] = l;
llist.push_back(root->data);
}
Buildfunction(root->left,d--,l++);
Buildfunction(root->right,d++,l++);
}
where d pointing to vertical distance from current node respect to root
and l pointing to level of the current node starting from 0
The following python solution worked for me. It handles all the cases.
Based on the solution of #azt
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def printLeaves(root):
if (root):
printLeaves(root.left)
if root.left is None and root.right is None:
print(root.data),
printLeaves(root.right)
def printBoundaryC(node):
if not node.left or not node.right:
print(node.data)
if node.left:
printBoundaryC(node.left)
if node.right:
printBoundaryC(node.right)
def printBoundaryLeft(root):
print(root.data)
if root.left:
printBoundaryLeft(root.left)
if root.right:
printBoundaryC(root.right)
def printBoundaryRight(root):
if root.right:
printBoundaryRight(root.right)
elif root.left:
printBoundaryC(root.left)
print(root.data)
def printBoundary(root):
if (root):
print(root.data)
if root.left:
printBoundaryLeft(root.left)
if root.right:
printBoundaryRight(root.right)
root = Node(20)
root.left = Node(8)
root.left.left = Node(4)
root.left.right = Node(12)
root.left.right.left = Node(10)
root.left.right.left.right = Node(5)
root.left.right.right = Node(14)
root.right = Node(22)
root.right.right = Node(25)
printBoundary(root)

Get the distance from a root to a node with given value in a binary tree: Algorithm correctness

Here's my code
public int getDist(Node root, int value)
{
if (root == null && value !=0)
return -1;//
if(root.value == value)// we have a match
return 0;
if(root.getLeft()!=null)
int left =1+ getDist(root.getLeft(),value);
int right = 1+getDist(root.getRight(),value);
if(left ==-1 && right== -1)
return -1;//not found
return Math.max(left,right);
}
I would appreciate any feedback on the correctness of the above approach or any optimizations.
As it stands your code won't work as intended. Consider this on the other hand:
public int getDist(Node root, int value) {
// value is never in an empty subtree
if (root == null)
return -1;
// found value, distance from root is 0
if(root.value == value)
return 0;
// find distance from root of left subtree
int left = getDist(root.getLeft(),value);
// find distance from root of right subtree
int right = getDist(root.getRight(),value);
// value not found in either subtree
if(left == -1 && right == -1)
return -1;
// if the value was found,
// return the distance from the root of the subtree + 1
return 1 + Math.max(left,right);
}
All I changed was remove some superfluous checks and move the +1 after the check for "value not in either subtree". The effect this has is the following: if the recursion finds that the value is not in a subtree, then the return statements will ripple up the value -1 all the way to the root of the subtree without changing it, keeping the information "value not here" intact. If the value was found in at least one subtree, then it can't be that both left and right are -1 so that check will fail and the return statement at the end will give back the intended value.
Let int? indicate a variant type that is either an int or null. In C# this is Nullable<int>, in C++11 this is std::optional<int>, etc.
Then the following code will work. It is only slightly modified from your code, with the key difference being the use of min instead of max.
int? dist(Node root, int value)
{
if (root == null) return null;
if (root.value == value) return 0;
int? left = dist(root.left, value);
int? right = dist(root.right, value);
if (left == null && right == null) return null;
if (left != null && right != null) return 1 + min(left, right);
if (left != null) return 1 + left;
return 1 + right;
}
If you want, you can just use int and replace the appropriate occurrences of null with some special value like -1. It's my personal preference to use a nullable/optional value because it seems clearer, but it's by no means required for this problem.

number of leaves in a binary tree

I am a beginner to binary trees and have been working my way through the algorithms book. I have learnt about the various traversal methods of BSTs (pre-order, post order etc).
Could someone please explain how one can traverse a BST to count the number of nodes that are leaves (no children) please?
Many thanks!
Use a recursive method:
For a leaf return 1.
For a non-leaf, return the sum of that method applied to its children.
Example in PHP:
class BST {
public $left; // The substree containing the smaller entries
public $right; // The substree containing the larger entries
public $data; // The value that is stored in the node
}
function countLeafs(BST $b) {
// Test whether children exist ...
if ($b->left || $b->right) {
// ... yes, the left or the right child exists. It's not a leaf.
// Return the sum of calling countLeafs() on all children.
return ($b->left ? countLeafs($b->left) : 0)
+ ($b->right ? countLeafs($b->right) : 0);
} else {
// ... no, it's a leaf
return 1;
}
}
The different traversal methods would lead to different algorithms (although for a simple problem like this, all DFS variants are more or less the same).
I assume that you have a BST which consists of objects of type Node. A node has two fields left and right of type Node, which are the children of the node. If a child is not present, the value of that field is null. The whole tree is referenced by a reference to the root, called root. In java:
class Node {
public Node left;
public Node right;
}
Node root;
A DFS is easiest to implement by recursion: define a method
int numberOfLeafs(Node node)
which returns the number of leafs in the subtree rooted by node. Of course, numberOfLeafs(root) should yield the number of leafs of the whole tree.
As said, it is really artificial to distinguish pre-, in-, and post-order traversal here, but I'm gonna do it anyway:
Pre-order DFS: First deal with the current node, then with the children
int numberOfLeafs(Node node) {
int result = 0;
if (node.left == null && node.right == null)
result += 1;
if (node.left != null)
result += numberOfLeafs(node.left)
if (node.right != null)
result += numberOfLeafs(node.right)
return result;
}
In-order DFS: First deal with the left child, then with the current node, then with the right child
int numberOfLeafs(Node node) {
int result = 0;
if (node.left != null)
result += numberOfLeafs(node.left)
if (node.left == null && node.right == null)
result += 1;
if (node.right != null)
result += numberOfLeafs(node.right)
return result;
}
Post-order DFS: First deal with the children, then with the current node
int numberOfLeafs(Node node) {
int result = 0;
if (node.left != null)
result += numberOfLeafs(node.left)
if (node.right != null)
result += numberOfLeafs(node.right)
if (node.left == null && node.right == null)
result += 1;
return result;
}
For a BFS, you typically use a simple loop with a queue in which you add unvisited vertices. I now assume that I have a class Queue to which I can add nodes at the end and take nodes from the front:
Queue queue = new Queue();
queue.add(root);
int numberOfLeafs = 0;
while (!queue.empty) {
// take an unhandled node from the queue
Node node = queue.take();
if (node.left == null && node.right == null)
numberOfLeafs += 1;
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
try this
int countLeafNodes(BTNode node) {
if (node == null)
return 0;
if (node.getLeftChild() == null && node.getRightChild() == null
&& node.getParent() != null)//this is a leaf, no left or right child
return 1;
else
return countLeafNodes(node.getLeftChild())
+ countLeafNodes(node.getRightChild());
}
which recursively counts leaf nodes for left and right sub trees and returns the total count

PreOrder Successor of a Node in BST

I'm trying this question for sometime but couldn't figure out the algorithm. My preference is to do it iteratively. Till now, I've figure out something but not sure on some point.
Currently, My algorithm looks like:
First traverse the tree to find the node
While traversing the tree, keep track of the previous node.
if you find the node, check if left child is present then that is successor return.
if left child is not present then check if right child is present the that is successor and return.
if the node(is left to the parent) and don't have left or right child then we've saved the prev node earlier then either prev or prev's right child is the successor.
But what if the node we found is in the right to parent and don't have left or right child how to find successor of this node?
May be there are many flaws in this algorithm as still I've not understand all the cases properly. If anyone has any idea or algorithm please share.
Thanks in advance.
when you find a node in preorder, to find its successor is just travesing to its next node.
what I was thinking first is the relationship of a node and its successor's values in pre-oder, but I found that it seems not very clear like the relationship in in-order. I think there is only one step beteen a node and its successor(if exists) : just move on travesing. So I design this algorithm.
my algorithm below is based on preorder travesal, it can run on a binary tree,not only BST.
#define NOT_FOUND -1
#define NEXT 0
#define FOUND 1
struct node {
struct node *p;//parent,but useless here
struct node *l;//left child
struct node *r;//right child
int value;
};
int travese(struct node* bnode, int* flag,int value)
{
if(bnode == NULL)
return 0;
else
{
if(*flag == FOUND)
//when the successor is found,do pruning.
return 1;
else if(*flag == NEXT) {
printf("successor:%d\n",bnode->value);
*flag = FOUND;
return 1;
}
else if(*flag == NOT_FOUND && bnode->value == value)
*flag = NEXT;
travese(bnode->l,flag,value);
travese(bnode->r,flag,value);
}
return 0;
}
and use it by:
int flag = NOT_FOUND;
travese(root,&flag,value);
if(flag == NEXT || flag == NOT_FOUND)
printf("no successor.\n");
EDIT:
turning a recurrence algorithm to a iterative one is not difficult by using a stack like below:
int preorder_travese_with_stack(struct node* bnode, int* flag,int value)
{
if(bnode == NULL)
return 0;
struct stack s;//some kind of implement
push(s,bnode);
while(NotEmpty(s) && *flag) {
struct node *curNode = pop(s);
if(*flag == NEXT) {
printf("successor:%d\n",curNode->value);
*flag = FOUND;
return 1;
}
else if(*flag == NOT_FOUND && curNode->value == value)
*flag = NEXT;
push(s,curNode->r);
push(s,curNode->l);
}
return 0;
}
but according to your comment and original description, I think the one you want is iterative algorithm without a stack.here it is.
After thinking ,searching and trying, I wrote one. When travse the tree iteratively without stack , the parent of a node is not useless any more. In a path, some nodes is visited not only once, and you need to record its direction at that time.
int preorder_travese_without_stack(struct node *root,int value,int *flag)
{
int state=1;
//state: traveral direction on a node
//1 for going down
//2 for going up from its left chlid
//3 for going up from its right child
struct node *cur = root;
while(1) {
if(state == 1) //first visit
{
//common travese:
//printf("%d ",cur->value);
if(cur->value == value && *flag == NOT_FOUND)
*flag = NEXT;
else if (*flag==NEXT) {
*flag = FOUND;
printf("successor:%d\n",cur->value);
break;
}
}
if((state == 1)&&(cur->l!=NULL))
cur = cur->l;
else if((state==1)&&(cur->l==NULL))
{
state = 2;
continue;
}
else if(state==2) {
if(cur->r != NULL ) {
cur=cur->r;
state = 1;
}
else
{
if(cur->p!=NULL)
{
if(cur==cur->p->r)
state = 3;
//else state keeps 2
cur=cur->p;
}
else //cur->p==NULL
{
if(cur->p->r!=NULL)
{
cur=cur->p->r;
state = 1;
}
else
break;
//end up in lchild of root
//because root's rchild is NULL
}
}
continue;
}
else //state ==3
{
if(cur->p!=NULL)
{
if(cur==cur->p->l)
state = 2;
else
state = 3;
cur=cur->p;
continue;
}
else
break;
}
}
}
the usage is the same as the first recurrence one.
If you are confused yet,mostly about the direction of a node , you can draw a tree and draw the path of pre-order traverse on paper,it would help.
I'm not sure there are bugs left in the code,but it works well on the tree below:
0
/ \
1 2
/ \ / \
3 4 5 6
btw,"wirte down pre-order (or else) travese algorithm of a tree both by recurrence and iteration" is a common interview problem, although solving the latter by a stack is permitted.but I think the BST requirement is unnecessary in pre-order travese.
My implementation of the algorithm does not use the key. Therefore it is possible to use it in any kind of binary tree, not only in Binary search trees.
The algorith I used is this:
if given node is not present, return NULL
if node has left child, return left child
if node has right child, return right child
return right child of the closest ancestor whose right child is present and not yet processed
Bellow there is my solution.
TreeNode<ItemType>* CBinaryTree<ItemType>::succesorPreOrder(TreeNode<ItemType> *wStartNode)
{
//if given node is not present, return NULL
if (wStartNode == NULL) return NULL;
/* if node has left child, return left child */
if (wStartNode->left != NULL) return wStartNode->left;
/* if node has right child, return right child */
if (wStartNode->right != NULL) return wStartNode->right;
/* if node isLeaf
return right child of the closest ancestor whose right child is present and not yet processed*/
if (isLeaf(wStartNode)) {
TreeNode<ItemType> *cur = wStartNode;
TreeNode<ItemType> *y = wStartNode->parent;
while (y->right == NULL && y->parent!=NULL){
cur = y;
y = y->parent;
}
while (y != NULL && cur == y->right) {
cur = y;
y = y->parent;
}
return y->right;
}
}
bool CBinaryTree<ItemType>::isLeaf(TreeNode<ItemType> *wStartNode){
if (wStartNode->left == NULL && wStartNode->right == NULL) return true;
else return false;
};

How to find the deepest path from root made up of only 1's in a binary search tree?

We have a binary tree (not a BST) made up of only 0s and 1s. we need to find the deepest 1 with a path from root made up only of 1's
Source : Amazon interview Q
public static int findMaxOnesDepth(Node root){
if(root != null && root.getValue() == 1){
return Math.max(1 + findMaxOnesDepth(root.getLeft()),
1 + findMaxOnesDepth(root.getRight());
}
else {
return 0;
}
}
If the node you are on is a '0', then the depth of '1's is 0. Otherwise, if the node you are on is a '1', then add 1 to the maximum 'one's depth' of both your left and right children - and return the maximum of those.
The above code finds the length, to find the actual nodes along the path, you could use a list to keep track of this
public static ArrayList<Node> findLongestOnesPath(Node root){
ArrayList<Node> currStack = new ArrayList<Node>();
if( root != null && root.getValue() == 1){
currStack.add(root);
ArrayList<Node> leftStack = findLongestOnesPath(root.getLeft());
ArrayList<Node> rightStack = findLongestOnesPath(root.getRight());
if(leftStack.size() > rightStack.size()){
currStack.addAll(leftStack);
}
else{
currStack.addAll(rightStack);
}
}
return currStack;
}

Resources