Print the longest path starting from root in a binary tree - python

In this tree:
a
/ \
b d
/ / \
c e f
/
g
The longest path starting from the root would be a-d-f-g
Here is my attempt:
class Node:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def print_path(root):
if not root:
return []
if root.left is None:
return [root.val].append(print_path(root.right))
elif root.right is None:
return [root.val].append(print_path(root.left))
elif (root.right is None) and (root.left is None):
return [root.val]
else:
return argmax([root.val].append(print_path(root.left)), [root.val].append(print_path(root.right)))
def argmax(lst1, lst2):
return lst1 if len(lst1) > len(lst2) else lst2
if __name__ == '__main__':
root_node = Node('a')
root_node.left = Node('b')
root_node.right = Node('c')
root_node.right.right = Node('f')
print print_path(root_node)
The tree in the main() function is not the example I have shown. For this tree the expected results would be a-c-f. This tree is shown below:
a
/ \
b c
\
f
Right now, I get
TypeError: object of type 'NoneType' has no len()
I'm not sure how None is showing up there since I have base cases.
Thanks!

Here's a working implementation:
class Node:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def print_path(root):
rightpath = []
leftpath = []
path = []
if root is None:
return []
if (root.right is None) and (root.left is None):
return [root.val]
elif root.right is not None:
rightpath = [root.val] + print_path(root.right)
elif root.left is not None:
leftpath = [root.val] + print_path(root.left)
return argmax(rightpath, leftpath)
def argmax(lst1, lst2):
return lst1 if len(lst1) > len(lst2) else lst2
root_node = Node('a')
root_node.left = Node('b')
root_node.right = Node('c')
root_node.right.right = Node('f')
print print_path(root_node)
Couple of issues with your code:
1) checking root.left is None before (root.right is None) and (root.left is None) is incorrect - you'll never reach (root.right is None) and (root.left is None)
2) instead of returning immediately, you want to use recursion and compare both branches and then return the branch with the longest path so far
3) append appends in place, so you need to store it in a variable
Edit:
Cleaner implementation (see comments)
class Node:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def print_path(root):
rightpath = []
leftpath = []
if root is None:
return []
rightpath = [root.val] + print_path(root.right)
leftpath = [root.val] + print_path(root.left)
return argmax(rightpath, leftpath)
def argmax(lst1, lst2):
return lst1 if len(lst1) > len(lst2) else lst2
root_node = Node('a')
root_node.left = Node('b')
root_node.right = Node('c')
root_node.right.right = Node('f')
print print_path(root_node)

You can simplify your logic significantly by allowing one more level of recursion and letting the main logic handle what were (confusing) special cases before:
def print_path(root):
if root is None:
return []
return [root.val] + argmax(print_path(root.right), print_path(root.left))

My solution
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
*Longest Path from root to leaf Node
* */
public class LongestPath {
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
Node root =bt.constructTree(bt);
List path = printPath(root);
Iterator itr = path.iterator();
while (itr.hasNext()){
System.out.print(itr.next() +" ");
}
}
public static List<Integer> printPath(Node root){
if(root ==null){
return null;
}
List<Integer> path = new ArrayList<>();
path.add(root.data);
List result = getMaxList(printPath(root.left), printPath(root.right));
if(result!=null) {
path.addAll(result);
}
return path;
}
public static List<Integer> getMaxList(List<Integer> list1, List<Integer> list2){
if(list1==null && list2==null){
return null;
}
if(list1==null){
return list2;
}
if(list2 == null){
return list1;
}
if(list1.size()> list2.size()){
return list1;
}else {
return list2;
}
}
}
Binary Tree
class Node
{
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree
{
Node root;
/* Get width of a given level */
int getWidth(Node node, int level)
{
if (node == null)
return 0;
if (level == 1)
return 1;
else if (level > 1)
return getWidth(node.left, level - 1)
+ getWidth(node.right, level - 1);
return 0;
}
/* UTILITY FUNCTIONS */
/* Compute the "height" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(Node node)
{
if (node == null)
return 0;
else
{
/* compute the height of each subtree */
int lHeight = height(node.left);
int rHeight = height(node.right);
/* use the larger one */
return (lHeight > rHeight) ? (lHeight + 1) : (rHeight + 1);
}
}
/* Driver program to test above functions */
public Node constructTree( BinaryTree tree) {
/*
Constructed binary tree is:
1
/ \
2 3
/ \ \
4 5 8
/ \
6 7
*/
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
tree.root.right.right = new Node(8);
tree.root.right.right.left = new Node(6);
tree.root.right.right.right = new Node(7);
return tree.root;
}
}
OUTPUT
1 3 8 7

The code should be edited as:
if (root.right is None) and (root.left is None):
return [root.val]
if root.right is not None:
rightpath = [root.val] + print_path(root.right)
if root.left is not None:
leftpath = [root.val] + print_path(root.left)
return argmax(rightpath, leftpath)
or the recursive function will always pass print_path(root.left) if the right.root is not None.

Below is a C++ implementation.
void longest_root_to_leaf_path(Node *root, std::vector<int> current_path,
std::vector<int> &longest_path) {
if (!root)
return;
current_path.push_back(root->data);
if (root->left == nullptr && root->right == nullptr) {
if (current_path.size() > longest_path.size())
longest_path = current_path;
return;
}
longest_root_to_leaf_path(root->left, current_path, longest_path);
longest_root_to_leaf_path(root->right, current_path, longest_path);
current_path.pop_back();
}

the above program was wrong in another case
elif root.left is not None:
leftpath = [root.val] + print_path(root.left)
elif root.right is not None:
rightpath = [root.val] + print_path(root.right)
if you give like this the output would become [a,b] only which is not expected output

Related

Binary search tree lazy deletion Python

I've created a binary search tree class and I'm trying to get a grasp on how "lazy deletion" works.
I've set a flag in order to show if a node has been removed. When I search for a value that I want to remove, self.removed would be marked as True. However, when I use the findValue method, it still says that the removed value is still there.
I've been doing some research on how lazy deletion works and all of them say that you need to set a flag and set it to True if the value is found. Is there anything else I would need to implement in order to get this to work? Or am I missing something?
Any help would be appreciated!
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
self.removed = False
def setLeft(self, left):
self.left = left
def setRight(self, right):
self.right = right
def getLeft(self):
return self.left
def getRight(self):
return self.right
def getValue(self):
return self.value
class Tree:
def __init__(self):
self.root = None
def insertValue(self, value):
"""add a new node containing value to the tree """
if self.root is None:
temp = Node(value)
self.root = temp
return
self.recInsertValue(value, self.root)
def recInsertValue(self, value, ptr):
if value < ptr.value:
if ptr.getLeft() is None:
temp = Node(value)
ptr.left = temp
else:
self.recInsertValue(value, ptr.getLeft())
else:
if ptr.right is None:
temp = Node(value)
ptr.right = temp
else:
self.recInsertValue(value, ptr.right)
def findValue(self, value):
"""return true if there is a node containing value, false otherwise"""
ptr = self.root
while ptr is not None:
if ptr.value == value:
return True
if value < ptr.value:
ptr = ptr.getLeft()
else:
ptr = ptr.getRight()
return False
def removeValue(self, value):
ptr = self.root
while ptr is not None:
if ptr.value == value:
ptr.removed = True
return True
if value < ptr.value:
ptr = ptr.getLeft()
else:
ptr = ptr.getRight()
return False
def inOrder(self):
return self.recInOrder(self.root)
def recInOrder(self, ptr):
buffer = ""
if ptr is not None:
buffer += self.recInOrder(ptr.getLeft())
buffer += str(ptr.getValue()) + " "
buffer += self.recInOrder(ptr.getRight())
return buffer
return ""
You should also modify the search method, otherwise there is no way to utilize the removed flag.
def findValue(self, value):
"""return true if there is a node containing value, false otherwise"""
ptr = self.root
while ptr is not None:
if ptr.value == value and not ptr.removed:
return True
if value < ptr.value:
ptr = ptr.getLeft()
else:
ptr = ptr.getRight()
return False
Also don't forget recInOrder:
def recInOrder(self, ptr):
buffer = ""
if ptr is not None:
buffer += self.recInOrder(ptr.getLeft())
buffer += str(ptr.getValue()) + " " if not ptr.removed else ""
buffer += self.recInOrder(ptr.getRight())
return buffer
return ""

lowest common ancestor (LCA) of two given nodes; getting null for one set of values; getting correct answer for another set

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8;
expected Output = 6; My output = 6
root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4;
expected Output = 2; My output = null
On using print I am getting the required value but when I return its null.
I think I am missing something very basic here.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
def bst(root,p=p.val,q=q.val):
if not root:
return
if p<root.val and q<root.val:
bst(root.left)
elif p>root.val and q>root.val:
bst(root.right)
else:
return root
return bst(root)
You may want to try the following implementation:
def lca(root, p, q):
if root is None:
return None
if(root.val > p.val and root.val > q.val):
return lca(root.left, p, q)
if(root.val < p.val and root.val < q.val):
return lca(root.right, p, q)
return root

Write a method buildTree() in Python to form a Binary Tree from a parent array

I can construct a Binary Tree in level order when I have a parent array, but I can't figure out how to construct it when we have 'N' in the array, representing Null.
For example, if the parent array is [3, 9, 20, N, N, 15, 7], the tree is:
Click to view the Binary Tree
I have the C++ code for the same, but I'm unable to figure out the Python code.
The C++ code is as follows:
struct Node
{
int data;
struct Node *left;
struct Node *right;
Node(int val) {
data = val;
left = right = NULL;
}
};
Node* buildTree(string str)
{
// Corner Case
if(str.length() == 0 || str[0] == 'N')
return NULL;
// Creating vector of strings from input
// string after spliting by space
vector<string> ip;
istringstream iss(str);
for(string str; iss >> str; )
ip.push_back(str);
// Create the root of the tree
Node *root = new Node(stoi(ip[0]));
// Push the root to the queue
queue<Node*> queue;
queue.push(root);
// Starting from the second element
int i = 1;
while(!queue.empty() && i < ip.size()) {
// Get and remove the front of the queue
Node* currNode = queue.front();
queue.pop();
// Get the current node's value from the string
string currVal = ip[i];
// If the left child is not null
if(currVal != "N") {
// Create the left child for the current Node
currNode->left = new Node(stoi(currVal));
// Push it to the queue
queue.push(currNode->left);
}
// For the right child
i++;
if(i >= ip.size())
break;
currVal = ip[i];
// If the right child is not null
if(currVal != "N") {
// Create the right child for the current node
currNode->right = new Node(stoi(currVal));
// Push it to the queue
queue.push(currNode->right);
}
i++;
}
return root;
}
In Python you could use this function:
def buildTree(lst):
def grab(it, nextlevel):
value = next(it, "N")
if value != "N":
node = Node(value)
nextlevel.append(node)
return node
# Create the root of the tree
it = iter(lst)
nextlevel = []
root = grab(it, nextlevel)
while nextlevel:
level = nextlevel
nextlevel = []
for node in level:
node.left = grab(it, nextlevel)
node.right = grab(it, nextlevel)
return root
Example call:
lst = [3, 9, 20, "N", "N", 15, 7]
root = buildTree(lst)

Insert a Node at the Tail of a Linked List python HackerRank

Its a very simple program of adding a node at the end of a link list. I dont know what mistake I am doing. has it something to do with the exoected output of hackerRank or there's a mistake in my code.
I m trying to implement the Python2
class Node(object):
def __init__(self, data=None, next_node=None):
self.data = data
self.next = next_node
def Insert(head, data):
if (head.head == None):
head.head = Node(data)
else:
current = head.head
while (current.next != None) and (current.data == data):
current = current.next
current.next = Node(data)
Heres a link to the question.
https://www.hackerrank.com/challenges/insert-a-node-at-the-tail-of-a-linked-list
If you have to add at the end of linklist then It's not needed to test current.data == data, Below code should be enough-
def Insert(head, data):
if (head == None):
head = Node(data)
else:
current = head
while (current.next != None):
current = current.next
current.next = Node(data)
return head
Also note that Python you don't need to use () after if and while.
Your code has several problems:
head is either None or an instance of Node. Neither has a
head attribute, so head.head makes no sense.
None is a singleton, so test something is None instead of something == None and something is not None instead of something != None.
You're supposed to return the head of the modified list. Your function doesn't return anything.
This one will ran through HackerRank interpreter for python3
#print ('This is start of the function')
node = SinglyLinkedListNode(data)
if (head == None):
head = node
else:
current = head
while (current.next != None):
current = current.next
current.next = node
return head
here's the answer -
#!/bin/python3
import math
import os
import random
import re
import sys
class SinglyLinkedListNode:
def __init__(self, node_data):
self.data = node_data
self.next = None
class SinglyLinkedList:
def __init__(self):
self.head = None
def print_singly_linked_list(node, sep, fptr):
while node:
fptr.write(str(node.data))
node = node.next
if node:
fptr.write(sep)
def insertNodeAtTail(head, data):
item = SinglyLinkedListNode(data)
if head is None:
head = item
else:
n = head
while(n.next):
n = n.next
n.next = item
return head
Node Class:
class Node(object):
def init(self, item):
self.data = item
self.next = None
def getdata(self):
return self.data
def setdata(self, item):
self.data = item
def getnext(self):
return self.next
def setnext(self, item):
self.next = item
and method to insert at the end is
def insert(head, item):
newNode = Node(item)
newNode.setdata(item)
current = head
while current.getnext() != None:
current = current.getnext()
current.setnext(newNode)
for a separate recursive version:
def getTail(node):
if node.next == None:
return node
return getTail(node.next)
def Insert(head, data):
if head == None:
return Node(data)
tail = getTail(head)
tail.next = Node(data)
return head
class SinglyLinkedListNode:
def __init__(self, node_data):
self.data = node_data
self.next = None
class SinglyLinkedList:
def __init__(self):
self.head = None
# Implementation
def insertNodeAtTail(head, data):
if head == None:
head = SinglyLinkedListNode(data)
else:
current = head
while current.next != None:
current = current.next
current.next = SinglyLinkedListNode(data)
return head
OK so I just implemented the whole thing on the problem question in Hackerrank and passed all the test case checks and here is the solution I guess... there is just one slight issue is that I have it done in Java... but I'll try my best to explain it...
First I have created a node for each addition to the tail.
Then I have added them by calling out the append function in the main method for the limit of the for loop.
With each call it adds the input integer data to the node and attaches it to the previous node in the list.
Finally prints it.
Kindly read the code, I have commented out the lines explaining what they do... don't worry I have tried to keep it as simple as possible for a python learner.
PS. Sorry, didn't see that this question was posted 6 years ago... well I just wanna keep this answer posted here so it might help another person out there in need.
GOOD LUCK AND KEEP LEARNING...
import java.io.*;
import java.util.*;
public class Solution {
// class Solution is what should be called as the LINKEDLIST class but its ok
Node head; // declaring a head for the LL
class Node { // Node class
int data; // the .data variable
Node ref; // .ref aka .next
Node(int data) { // constructor for initializing the values
this.data = data;
this.ref = null;
}
}
public void append(int data) { // i call 'to join at the end' as append
Node newnode = new Node(data); // new node creation
if (head == null) { // checking is head is null aka None in Py
head = newnode;
return;
}
Node curr = head; // assigning head to a curr node ready for traversal
while (curr.ref != null) { // traversal begins
curr = curr.ref;
} // traversal ends
curr.ref = newnode; // this is the last node where the join happens
}
public void p() { // i name printing function as p()
if (head == null) { // if head is null then print empty
System.out.println("Empty");
return;
}
Node curr = head; // same thing - traversal begins here
while (curr != null) {
System.out.println(curr.data);
curr = curr.ref;
} // by now all data values have been printed out already
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); // scanner class for input
Solution l = new Solution(); // object creating for LL as Solution class name
int numberOfNodes = sc.nextInt(); // input for number of NODEs in LL
for (int i = 0; i < numberOfNodes; i++) { // loop for .data values
int data = sc.nextInt();
l.append(data); // function append call for each (i)
}
l.p(); // finally print func call to display output LL
}
}

Help me understand Inorder Traversal without using recursion

I am able to understand preorder traversal without using recursion, but I'm having a hard time with inorder traversal. I just don't seem to get it, perhaps, because I haven't understood the inner working of recursion.
This is what I've tried so far:
def traverseInorder(node):
lifo = Lifo()
lifo.push(node)
while True:
if node is None:
break
if node.left is not None:
lifo.push(node.left)
node = node.left
continue
prev = node
while True:
if node is None:
break
print node.value
prev = node
node = lifo.pop()
node = prev
if node.right is not None:
lifo.push(node.right)
node = node.right
else:
break
The inner while-loop just doesn't feel right. Also, some of the elements are getting printed twice; may be I can solve this by checking if that node has been printed before, but that requires another variable, which, again, doesn't feel right. Where am I going wrong?
I haven't tried postorder traversal, but I guess it's similar and I will face the same conceptual blockage there, too.
Thanks for your time!
P.S.: Definitions of Lifo and Node:
class Node:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
class Lifo:
def __init__(self):
self.lifo = ()
def push(self, data):
self.lifo = (data, self.lifo)
def pop(self):
if len(self.lifo) == 0:
return None
ret, self.lifo = self.lifo
return ret
Start with the recursive algorithm (pseudocode) :
traverse(node):
if node != None do:
traverse(node.left)
print node.value
traverse(node.right)
endif
This is a clear case of tail recursion, so you can easily turn it into a while-loop.
traverse(node):
while node != None do:
traverse(node.left)
print node.value
node = node.right
endwhile
You're left with a recursive call. What the recursive call does is push a new context on the stack, run the code from the beginning, then retrieve the context and keep doing what it was doing. So, you create a stack for storage, and a loop that determines, on every iteration, whether we're in a "first run" situation (non-null node) or a "returning" situation (null node, non-empty stack) and runs the appropriate code:
traverse(node):
stack = []
while !empty(stack) || node != None do:
if node != None do: // this is a normal call, recurse
push(stack,node)
node = node.left
else // we are now returning: pop and print the current node
node = pop(stack)
print node.value
node = node.right
endif
endwhile
The hard thing to grasp is the "return" part: you have to determine, in your loop, whether the code you're running is in the "entering the function" situation or in the "returning from a call" situation, and you will have an if/else chain with as many cases as you have non-terminal recursions in your code.
In this specific situation, we're using the node to keep information about the situation. Another way would be to store that in the stack itself (just like a computer does for recursion). With that technique, the code is less optimal, but easier to follow
traverse(node):
// entry:
if node == NULL do return
traverse(node.left)
// after-left-traversal:
print node.value
traverse(node.right)
traverse(node):
stack = [node,'entry']
while !empty(stack) do:
[node,state] = pop(stack)
switch state:
case 'entry':
if node == None do: break; // return
push(stack,[node,'after-left-traversal']) // store return address
push(stack,[node.left,'entry']) // recursive call
break;
case 'after-left-traversal':
print node.value;
// tail call : no return address
push(stack,[node.right,'entry']) // recursive call
end
endwhile
Here is a simple in-order non-recursive c++ code ..
void inorder (node *n)
{
stack s;
while(n){
s.push(n);
n=n->left;
}
while(!s.empty()){
node *t=s.pop();
cout<<t->data;
t=t->right;
while(t){
s.push(t);
t = t->left;
}
}
}
def print_tree_in(root):
stack = []
current = root
while True:
while current is not None:
stack.append(current)
current = current.getLeft();
if not stack:
return
current = stack.pop()
print current.getValue()
while current.getRight is None and stack:
current = stack.pop()
print current.getValue()
current = current.getRight();
def traverseInorder(node):
lifo = Lifo()
while node is not None:
if node.left is not None:
lifo.push(node)
node = node.left
continue
print node.value
if node.right is not None:
node = node.right
continue
node = lifo.Pop()
if node is not None :
print node.value
node = node.right
PS: I don't know Python so there may be a few syntax issues.
Here is a sample of in order traversal using stack in c# (.net):
(for post order iterative you may refer to: Post order traversal of binary tree without recursion)
public string InOrderIterative()
{
List<int> nodes = new List<int>();
if (null != this._root)
{
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
var iterativeNode = this._root;
while(iterativeNode != null)
{
stack.Push(iterativeNode);
iterativeNode = iterativeNode.Left;
}
while(stack.Count > 0)
{
iterativeNode = stack.Pop();
nodes.Add(iterativeNode.Element);
if(iterativeNode.Right != null)
{
stack.Push(iterativeNode.Right);
iterativeNode = iterativeNode.Right.Left;
while(iterativeNode != null)
{
stack.Push(iterativeNode);
iterativeNode = iterativeNode.Left;
}
}
}
}
return this.ListToString(nodes);
}
Here is a sample with visited flag:
public string InorderIterative_VisitedFlag()
{
List<int> nodes = new List<int>();
if (null != this._root)
{
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
BinaryTreeNode iterativeNode = null;
stack.Push(this._root);
while(stack.Count > 0)
{
iterativeNode = stack.Pop();
if(iterativeNode.visted)
{
iterativeNode.visted = false;
nodes.Add(iterativeNode.Element);
}
else
{
iterativeNode.visted = true;
if(iterativeNode.Right != null)
{
stack.Push(iterativeNode.Right);
}
stack.Push(iterativeNode);
if (iterativeNode.Left != null)
{
stack.Push(iterativeNode.Left);
}
}
}
}
return this.ListToString(nodes);
}
the definitions of the binarytreenode, listtostring utility:
string ListToString(List<int> list)
{
string s = string.Join(", ", list);
return s;
}
class BinaryTreeNode
{
public int Element;
public BinaryTreeNode Left;
public BinaryTreeNode Right;
}
Simple iterative inorder traversal without recursion
'''iterative inorder traversal, O(n) time & O(n) space '''
class Node:
def __init__(self, value, left = None, right = None):
self.value = value
self.left = left
self.right = right
def inorder_iter(root):
stack = [root]
current = root
while len(stack) > 0:
if current:
while current.left:
stack.append(current.left)
current = current.left
popped_node = stack.pop()
current = None
if popped_node:
print popped_node.value
current = popped_node.right
stack.append(current)
a = Node('a')
b = Node('b')
c = Node('c')
d = Node('d')
b.right = d
a.left = b
a.right = c
inorder_iter(a)
State can be remembered implicitly,
traverse(node) {
if(!node) return;
push(stack, node);
while (!empty(stack)) {
/*Remember the left nodes in stack*/
while (node->left) {
push(stack, node->left);
node = node->left;
}
/*Process the node*/
printf("%d", node->data);
/*Do the tail recursion*/
if(node->right) {
node = node->right
} else {
node = pop(stack); /*New Node will be from previous*/
}
}
}
#Victor, I have some suggestion on your implementation trying to push the state into the stack. I don't see it is necessary. Because every element you take from the stack is already left traversed. so instead of store the information into the stack, all we need is a flag to indicate if the next node to be processed is from that stack or not. Following is my implementation which works fine:
def intraverse(node):
stack = []
leftChecked = False
while node != None:
if not leftChecked and node.left != None:
stack.append(node)
node = node.left
else:
print node.data
if node.right != None:
node = node.right
leftChecked = False
elif len(stack)>0:
node = stack.pop()
leftChecked = True
else:
node = None
Little Optimization of answer by #Emadpres
def in_order_search(node):
stack = Stack()
current = node
while True:
while current is not None:
stack.push(current)
current = current.l_child
if stack.size() == 0:
break
current = stack.pop()
print(current.data)
current = current.r_child
This may be helpful (Java implementation)
public void inorderDisplay(Node root) {
Node current = root;
LinkedList<Node> stack = new LinkedList<>();
while (true) {
if (current != null) {
stack.push(current);
current = current.left;
} else if (!stack.isEmpty()) {
current = stack.poll();
System.out.print(current.data + " ");
current = current.right;
} else {
break;
}
}
}
class Tree:
def __init__(self, value):
self.left = None
self.right = None
self.value = value
def insert(self,root,node):
if root is None:
root = node
else:
if root.value < node.value:
if root.right is None:
root.right = node
else:
self.insert(root.right, node)
else:
if root.left is None:
root.left = node
else:
self.insert(root.left, node)
def inorder(self,tree):
if tree.left != None:
self.inorder(tree.left)
print "value:",tree.value
if tree.right !=None:
self.inorder(tree.right)
def inorderwithoutRecursion(self,tree):
holdRoot=tree
temp=holdRoot
stack=[]
while temp!=None:
if temp.left!=None:
stack.append(temp)
temp=temp.left
print "node:left",temp.value
else:
if len(stack)>0:
temp=stack.pop();
temp=temp.right
print "node:right",temp.value
Here's an iterative C++ solution as an alternative to what #Emadpres posted:
void inOrderTraversal(Node *n)
{
stack<Node *> s;
s.push(n);
while (!s.empty()) {
if (n) {
n = n->left;
} else {
n = s.top(); s.pop();
cout << n->data << " ";
n = n->right;
}
if (n) s.push(n);
}
}
Here is an iterative Python Code for Inorder Traversal ::
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def inOrder(root):
current = root
s = []
done = 0
while(not done):
if current is not None :
s.append(current)
current = current.left
else :
if (len(s)>0):
current = s.pop()
print current.data
current = current.right
else :
done =1
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
inOrder(root)
For writing iterative equivalents of these recursive methods, we can first understand how the recursive methods themselves execute over the program's stack. Assuming that the nodes do not have their parent pointer, we need to manage our own "stack" for the iterative variants.
One way to start is to see the recursive method and mark the locations where a call would "resume" (fresh initial call, or after a recursive call returns). Below these are marked as "RP 0", "RP 1" etc ("Resume Point"). Take example of inorder traversal. (I will present in C language, but same methodology applies to any general language):
void in(node *x)
{
/* RP 0 */
if(x->lc) in(x->lc);
/* RP 1 */
process(x);
if(x->rc) in(x->rc);
/* RP 2 */
}
Its iterative variant:
void in_i(node *root)
{
node *stack[1000];
int top;
char pushed;
stack[0] = root;
top = 0;
pushed = 1;
while(top >= 0)
{
node *curr = stack[top];
if(pushed)
{
/* type (x: 0) */
if(curr->lc)
{
stack[++top] = curr->lc;
continue;
}
}
/* type (x: 1) */
pushed = 0;
process(curr);
top--;
if(curr->rc)
{
stack[++top] = curr->rc;
pushed = 1;
}
}
}
The code comments with (x: 0) and (x: 1) correspond to the "RP 0" and "RP 1" resume points in the recursive method. The pushed flag helps us deduce one of these two resume-points. We do not need to handle a node at its "RP 2" stage, so we do not keep such node on stack.
I think part of the problem is the use of the "prev" variable. You shouldn't have to store the previous node you should be able to maintain the state on the stack (Lifo) itself.
From Wikipedia, the algorithm you are aiming for is:
Visit the root.
Traverse the left subtree
Traverse the right subtree
In pseudo code (disclaimer, I don't know Python so apologies for the Python/C++ style code below!) your algorithm would be something like:
lifo = Lifo();
lifo.push(rootNode);
while(!lifo.empty())
{
node = lifo.pop();
if(node is not None)
{
print node.value;
if(node.right is not None)
{
lifo.push(node.right);
}
if(node.left is not None)
{
lifo.push(node.left);
}
}
}
For postorder traversal you simply swap the order you push the left and right subtrees onto the stack.

Categories

Resources