Print leaf nodes in a binary tree right to left? - data-structures

I'm looking for an answer for this:
Find the pseudo code of printing the leaf nodes in a binary tree, from
right to left.
I would be glad to hear some ideas. A hint (not a full solution, of course) or a link to a related topic that could assist me in understanding this issue would be helpful.

Perform a depth-first traversal of the tree, handling the right sub-trees first and printing only the leaf nodes.
The easiest way to implement this is with a recursive function.
void printLeafNodes(BinaryTreeNode* treePtr) {
if(treePtr.leftChild == null && treePtr.rightChild == null) {
//This is a leaf node; print its value
} else {
//Recurse on right subtree
if(treePtr.rightChild != null) {
printLeafNodes(treePtr.rightChild);
}
//Recurse on left subtree
if(treePtr.leftChild != null) {
printLeafNodes(treePtr.leftChild);
}
}
}
This page is pretty helpful for visualizing the solution: Tree Traversal.

void in(node* root){
if(root)
{
if(!root->left && !root->right)
cout<<root->data<<endl;
in(root->left);
in(root->right);
} }
You can do something like this(code in C++).
The idea behind this code is, do inorder traversal/ postorder traversal & check if the left & right children are NULL or not. If it's Null it means it's a leaf node.

You would need to use a recursive method by starting out with passing the method the top level node of a binary tree.
In the pseudocode, I'm assuming that each node is defined with "right" and "left" members that themselves are nodes and a "name" property, to print something about the node. The method could look like this, in no particular language since you said pseudocode:
function processNode(parent) {
if(parent.right = null AND parent.left = null)
print parent.name
if(parent.right <> null)
processNode(parent.right)
if(parent.left <> null)
processNode(parent.left)
}
Then you would start out with:
processNode(topNode)

Perform in-order traversal and add only leaf nodes to the list of visited nodes.
Revert the list.
Or
Actually when creating the list in step one keep adding node at the head and let it point to previous node(rather than previous node pointing to new node).

Print leaf nodes while doing the level order traversal in reverse order excluding the nodes which are not leaf.

Do Inoder/Preorder/postorder But for Right Child First Then go to left Child
void postOrder(Node* root)
{
if(root==NULL)
return;
postOrder(root->right);
postOrder(root->left);
if(root->left==NULL && root->right==NULL)
cout << root->data <<" ";
}

Presumably you know how to traverse a binary tree in order using recursion.
void visit(Node node) {
if(node.hasLeft()) {
visit(node.getLeft());
}
handleValue(node.value); // print or whatever
if(node.hasRight()) {
visit(node.getRight());
}
}
You'll notice that when you do this, you're already handling the leaves in left-to-right order, in addition to handling non-leaf nodes.
To visit right-to-left, just reverse the order of the statements -- so visit the right, then handle the value, then visit the left.
To print only leaf nodes, you just need to put an if statement around handleValue, telling it to only output if the node is a leaf. A node is a leaf if it has neither a left nor right child node.

python code
def Reverse_print(self):
if self.right:
self.right.Reverse_print()
print(self.data),
if self.left:
self.left.Reverse_print()
it is recursion , it goes always right until there is no right
then at last right it go back to the root print it then print left
so actually you are printing from biggest value to lowest
then back and so the same thing
then back and so the same thing
then back and so the same thing
bla...blaa..blaa

I know that I am resurrecting an old thread but I think that it may help others viewing this thread. If you are talking about interview question, i think that the recursive answer is only a small part of the answer and the interviewer will like to hear the iterative approach as well. The right to left traversal (printing) is not a regular pre/post/inorder traversals that described in wiki. The main idea here is that you need to go right as long as you can and start printing from the far right node first, then its parent and only then the left subtree.
Recursive:
printRightToLeft(Node root){
if (root == null)
return;
// You can check root.right and root.left for null before calling the
// printRightToLeft function to avoid pushing unneeded data to recursion
// call stack.
printRightToLeft(root.right);
if (root.right == null && root.left == null)
print(root);
printRightToLeft(root.left);
}
Iterative:
printRightToLeft(Node root){
if (root == null)
return;
Stack s = new Stack();
s.push(root);
while(!s.isEmpty()){
Node n = s.top();
if (n.right != null && !n.visited){
s.push(n.right);
n.visited = true;
} else {
s.pop();
if (n.right == null && n.left == null)
print(n);
if (n.left != null)
s.push(n.left);
}
}

Related

how should I find the shortest path in a single direction tree

I have a graph that is not binary, and is of single direction. It can look like the following:
I would like to find the shortest path, for example Team "G" to Team "D". What methods can I use?
By "of single direction" I imagine what you mean is that the tree is represented by nodes which only point at the children, not at the parents. Given that, user3386109's comment provides a simple way to get the answer you are looking for.
Find the path from the root to the first node by doing any tree traversal, like in-order (even if the order of children is insignificant, in practice, there will be some way to enumerate them in some order), and record the sequence of nodes from the root to the first node. In your example, we would get G-B-A (assuming a recursive solution where we are printing these nodes in reverse order).
Find the path from the root to the second node in the same way. Here, we'd get a path like D-A.
Find the first common ancestor of the two nodes; assuming the nodes are labeled uniquely as in this example, we can simply find the first symbol in either string of nodes, that is also in the other string of nodes. Regardless of which string we start with, we should get the same answer, as we do in your example: A
Chop off everything in both strings after the common ancestor, reverse one of the strings, and concatenate them with the common ancestor in the middle. This gives a path starting with node1 going to node2. Note that the problem asks for the shortest path; however, in a tree, there will be exactly one path between any two nodes. In your example, we get G-B-A-D.
Some pseudocode...
class Node {
char label;
Node[] children;
}
string FindPath(Node root, Node node1, Node node2) {
// make sure we have valid inputs
if (root == null || node1 == null || node2 == null) return null;
// look for paths to the nodes from the root
string path1 = FindPath(root, node1);
string path2 = FindPath(root, node2);
// one of the nodes wasn't found
if (path1 == null || path2 == null) return null;
// look for first common node
// note: this isn't the most efficient approach, see
// comments on time complexity below
for (int i = 0; i < path1.Length; i++) {
char label = path1[i];
if (path2.Contains(label) {
path1 = path1.Substring(0, i);
path2 = path2.Substring(0, path2.IndexOf(label);
return path1 + label + ReverseString(path2);
}
}
// will never reach here because it's guaranteed we will find
// a common ancestor in a tree
throw new Exception("Unreachable statement");
}
string FindPath(Node root, Node node) {
// make sure inputs are valid
if (root == null || node == null) return null;
if (root.label == node.label) {
// found the node
return node.label;
} else {
// this is not the node, exit early if no children
if (root.children == null || root.children.Count == 0) return null;
// check each child and if we find a path, return it
foreach (Node child in root.children) {
string path = FindPath(child, node);
if (path != null && path.Length > 0) {
return path + root.label;
}
}
// it's possible that the target node is not in this subtree
return null;
}
}
In terms of the number of nodes in the tree, the complexity should look like...
Getting the path from the root to each node should at worst visit each node in the tree, so O(|V|)
Looking for the first common node... well, a naive approach would be O(|V|^2) if we use the code as proposed above, since in the worst case, the tree is split in two long branches. But, we could be a little smarter and start at the end and work our way back as long as the strings match, and return the last matching node we saw as soon as we see that they don't match anymore (or we run out of symbols to check). Coding that is left as an exercise and that should be O(|V|)

How to transform a binary tree into a heap in place?

I have thought of the following:
Degenerate the tree into a linked list, and while degenerating, make
a dynamic array with the node object and its index in the linked
list
It would look like this
def treeDegenerator(self):
self.valList = []
currentNode = self
self.totalNodes = 0
self.nodes = 0
while currentNode:
while currentNode.getLeftChild():
currentNode.rotate_root_right()
self.valList.append(currentNode)
currentNode = currentNode.getRightChild()
self.totalNodes += 1
use the dynamic array, dereference all left childs and right childs and transform the degenerated tree into a complete tree by
using (index value)*2+1 to get the left child, add 1 more for the right.
def completeTree():
for node in self.valList:
node.left = None
node.right = None
for i in range(len(self.valList)):
self.valList[i].left = self.valList[(i)*2+1]
self.valList[i].right = a.valList[(i)*2+2]
Turn into heap by shifting values by comparison of the children for each node, level by level,starting at the bottom.
This was a problem for which students had to code without any references on a past exam. The issue with my method is that, its pretty much impossible for me to write all that code down in 30 minutes properly, and maybe could be possible if i memorize some code before hand. I was wondering if theres an easier, more feasible and elegant solution to turn any binary tree into a heap in place?
Conceptually you can break this task down into two steps:
Rebuild the tree into a perfectly-balanced BST with the bottom row filled in from left-to-right. You can do this using a modified version of the Day-Stout-Warren algorithm.
Run the heapify algorithm to convert your tree into a binary heap. This can be done really beautifully recursively; see below for details.
The Day-Stout-Warren algorithm works by rotating the tree into a singly-linked list, then from there applying a series of rotations to turn it into a perfectly-balanced tree. I don't remember off the top of my head whether the DSW algorithm specifically will place all leftover nodes in the bottom layer of the tree on the far left, as needed by a binary heap. If not, you can fix this up by doing a cleanup pass: if the tree doesn't have a number of nodes that's a perfect power of two, remove all nodes from the bottom layer of the tree, then iterate over the tree with an inorder traversal to place them on the far left.
As for the heapify algorithm: the way this is typically done is by visiting the layers of the tree from the bottom toward the top. For each node, you repeatedly swap that node down with its smaller child until it's smaller than all its children. With an explicit tree structure, this can be done with an elegant recursive strategy:
If the tree has no children, stop.
Otherwise, recursively heapify the left and right subtrees, then perform a "bubble-down" pass of repeatedly swapping the root's value with its smaller child's value until it's in the right place.
This overall requires O(n) time and uses only O(log n) auxiliary storage space, which is the space you'd need for the stack frames to implement the two algorithms.
<editorializing> That being said - this seems like a really bad coding question to put on a 30-minute timed exam. You can have a great command of algorithms and how to code them up and yet not remember all the steps involved in the two substeps here. Asking for this in half an hour is essentially testing "have you memorized implementations of various unrelated algorithms in great detail?," which doesn't seem like a good goal. </editorializing>
I would first collapse the tree into an ordered linked list on node.right.
I'm assuming we started with an ordered BST. If not, then sort the list. If you want a max-heap instead of a min-heap, then reverse the list at this point, too.
Count the nodes and calculate the depth of the largest complete tree contained in the solution
Do a recursive preorder traversal of the complete tree, filling in each node from the head of the list as you go.
Do a pre-order traversal of the tree you just built, filling in leaves from list nodes until you run out
Step 4 would be accomplished recursively like this:
root = list
fillChildren(root, list.right, levels-1)
fillChildren(root, list, levels) {
if (levels < 1) {
root.left = root.right = null
return list
}
root.left = list
list = fillChildren(root.left, list.right, levels-1)
root.right = list
list = fillChildren(root.right, list.right, levels-1)
return list
}
The trick to this, of course, is that mapping nodes in order to a pre-order traversal satisfies the heap property.
It's also pretty easy to combine steps 4 and 5 just by keeping track of each node's index in an imaginary array heap.
Just for fun, here's the whole job:
treeToHeap(root) {
if (root == null) {
return null
}
// Convert tree to list
while(root.left != null) {
root = rotateRight(root)
}
for (n = root; n.right != null; n=n.right) {
while (n.right.left != null) {
n.right = rotateRight(n.right)
}
}
// Count nodes
count = 0
for (n = root; n!=null; n=n.right) {
count+=1
}
// Build min-heap
list = root.right
// root's index in imaginary array heap is 0
if (count>1) {
root.left = list
list = fillNodes(root.left, list.right, 1, count)
} else {
root.left = null
}
if (count>2) {
root.right = list
list = fillNodes(root.right, list.right, 2, count)
} else {
root.right = null
}
return root
}
fillNodes(root, list, heapIndex, heapSize) {
heapIndex = heapIndex*2+1
if (heapIndex < heapSize) {
root.left = list
list = fillNodes(root.left, list.right, heapIndex, heapSize)
} else {
root.left = null
}
heapIndex += 1
if (heapIndex < heapSize) {
root.right = list
list = fillNodes(root.right, list.right, heapIndex, heapSize)
} else {
root.right = null
}
return list
}
So that took 15 minutes (and I didn't bother to write out rotateRight), and that's after figuring out how to do it. And I returned a couple times to fix bugs.
For a 30 minute exam, it's quite tough... BUT maybe the exam didn't really require the heap to be perfectly balanced. If it's just a question of implementing an in-place heapify, then it's quite reasonable.

Is pre-order traversal a depth-first method?

Is pre-order traversal a depth-first algorithm? I'm using it in my search below.I have included the code below.
public bool DFS1(int value, BSTNode root)
{ // Pre-order search
if (root == null)
return false;
if (root.data == value)
{
Console.WriteLine("found");
return true;
}
DFS1(value, root.left); //vist the left node
return DFS1(value, root.right); // vist the right node.
}
Yes, it is depth-first: you will complete the left sub-tree completely before you look at the original root's right node. However, you need to consider the result from that left search. At the moment, this will return true iff the rightmost node has the target value.
return DFS1(value, root.left) or
DFS1(value, root.right)
Most compilers will optimize this (short-circuit), so that if the left side returns true, the right will not execute. If not, you can write it yourself:
if (DFS1(value, root.left))
return true;
else
return DFS1(value, root.right);

How to verify if a given tree is a Binary Search Tree or not [duplicate]

This question already has answers here:
How do you validate a binary search tree?
(33 answers)
Closed 8 years ago.
I wanted to know if a given binary tree is a binary search tree or not.
I don't know How to do that?
The only thing I know is that the inorder traversal of BST will gives you ascending order output.
So, is this the only condition we need to verify or is there anything else we are suppose to check.
In case if there are some other necessary conditions to be checked, What are they? and why those conditions are necessary to be checked? Because, I think, INORDER traversal itself can tell you easily if the given tree is BST or not.
Yes, if inorder traversal of the tree gives you a strictly monotonic list of values that is sufficient to determine that the tree is a BST.
By definition of Binary search tree, if every node of the binary tree satisfy the following conditions then it is a Binary Search Tree:
The left subtree of a node should contain only nodes with keys less than the node’s key
The right subtree of a node should contain only nodes with keys greater than the node’s key
Both the left and right subtrees must also be binary search trees.
All the above conditions are verified if the inorder traversal is in ascending order.
Actually - it is not enough to just do an in order traversal - you also need to verify that each node's value follows the rules of the tree. In the case of a BST, the left child value is less than the node value and the right child value is greater than the node value. Here is a recursive example in Java.
private static boolean isBST(Node current, Comparable more, Comparable less) {
if (current == null)
return true;
if (less != null && current.value.compareTo(less) > 0)
return false;
if (more != null && current.value.compareTo(more) < 0)
return false;
return isBST(current.left, more, current.value) &&
isBST(current.right, current.value, less);
}
public static boolean isBST(BinarySearchTree tree) {
return isBST(tree.getRoot(), null, null);
}
While doing In-Order traversal, we can keep track of previously visited node
Code:
bool isBST(struct node* root)
{
static struct node *prev = NULL;
// traverse the tree in inorder fashion and keep track of prev node
if (root)
{
if (!isBST(root->left))
return false;
// Allows only distinct valued nodes
if (prev != NULL && root->data <= prev->data)
return false;
prev = root;
return isBST(root->right);
}
return true;
}
A simple but elegant recursive solution in Java:
public static boolean isBST(TreeNode node, int leftData, int rightData)
{
if (node == null) return true;
if (node.getData() > leftData || node.getData() <= rightData) return false;
return (isBST(node.left, node.getData(), rightData)
&& isBST(node.right, leftData, node.getData()));
}
The initial call to this function can be something like this:
if (isBST(root, Integer.MAX_VALUE, Integer.MIN_VALUE))
System.out.println("This is a BST.");
else
System.out.println("This is NOT a BST!");
Essentially we keep creating a valid range (starting from [ MIN_VALUE, MAX_VALUE]) and keep shrinking it down foe each node as we go down recursively.
Source: http://exceptional-code.blogspot.com/2011/08/binary-search-trees-primer.html

binary tree with special property

There is binary tree with special property that all its inner node have val = 'N' and all leaves have val = 'L'. Given its preorder. construct the tree and return the root node.
every node can either have two children or no child
Recursion is your friend.
Tree TreeFromPreOrder(Stream t) {
switch (t.GetNext()) {
case Leaf: return new LeafNode;
case InternalNode:
Node n = new Node;
n.Left = TreeFromPreOrder(t);
n.Right = TreeFromPreOrder(t);
return n;
default:
throw BadPreOrderException;
}
}
Looking at it as a recursive method, it becomes easy to see how do other things.
For instance, say we wanted to print the InOrder traversal. The code will look something like this:
void PrintInorderFromPreOrder(Stream t) {
Node n = new Node(t.GetNext());
switch (n.Type) {
case Leaf: return;
case InternalNode:
PrintInorderFromPreOrder(t);
print(n.Value);
PrintInorderFromPreOrder(t);
default:
throw BadPreOrderException;
}
}
Also, I would like to mention that this is not that artificial. This type of representation can actually be used to save space when we need to serialize a binary tree: Efficient Array Storage for Binary Tree.
Just the basic idea: keep a stack where the head is the "current" node and read sequentially the string representing the preorder.
Now, if you encounter a 'L', then it means the "current" node has as a child a leaf, so you can "switch" to the right child and resuming building the corresponding subtree, pushing the root of that subtree; if, when encountering a 'L', the "current node" has already two children, pop an element from the stack.

Resources