Amazon Interview Question
Software Engineer / Developers//Using Two Stack
void postorder_traverse(struct tree *root)
{
struct tree *stack1[10],*stack2[10];
int top1=-1,top2=-1,t;
while(1)
{
while(root)
{
push(stack1,root,&top1);
push(stack2,root,&top2);
root=root->left;
}
if(top1==-1 && top2==-1)
break;
if(stack1[top1]==stack2[top2])
{
root = pop(stack1,&top1);
root=root->right;
}
else
{
root = pop(stack2,&top2);
printf("\t %d ",root->data);
root=NULL;
}
}
}
What Metta means is this (appears working to me):
Stack S, R;
S.push(head);
R.push(head);
while (S is not empty) {
n = S.pop();
if (n.right) { S.push(n.right); R.push(n.right); }
if (n.left) { S.push(n.left); R.push(n.left); }
}
print(R);
Correct solution but the order of the following two lines has to be reversed.First push the left child and then the right child.
Stack S, R;
S.push(head);
R.push(head);
while (S is not empty) {
n = S.pop();
if (n.left) { S.push(n.left); R.push(n.left); }
if (n.right) { S.push(n.right); R.push(n.right); }
}
print(R);
sorry - above solution given by Schultz is not correct.
Only one stack will do. Will use 3 special nodes RIGHT , LEFT and NULL also: RIGHT node means now move to right subtree, LEFT node means, now move to left subtree and NULL means, print the node.
void postOrder(Node root)
{
Node node, val;
Stack S;
S.push(RIGHT);
S.push(root);
while(!S.empty()
{
node = S.pop();
val = S.pop();
if(val == RIGHT)
{
if(node.right)
{
S.push(LEFT);
S.push(node);
S.push(RIGHT);
S.push(node.right);
}
else if(node.LEFT)
{
S.push(NULL);
S.push(node);
S.push(RIGHT);
S.push(node.LEFT);
}
else
print node;
}
else if(val == LEFT)
{
if(node.left)
{
S.push(NULL);
S.push(node);
S.push(RIGHT);
S.push(node.left);
}
}
else
print node;
}
}
#define LEFT 0
#define RIGHT 1
#define NONE 3
typedef struct binTreeNode{
int val;
int visited;
struct binTree* left;
struct binTree* right;
} nodeType;
postOrderTraversal(nodeType* node){
if ( node == NULL ){
return NULL;
}
while ( node != NULL ){
node->visited = LEFT;
push(node);
node = node->left;
}
while ( (node = pop()) != NULL ){
if (( node->visited == LEFT ) &&
( node->right != NULL )){
node->visited = RIGHT;
push(node);
node = node->right;
while ( node != NULL ){
node->visited = LEFT;
push(node);
node = node->left;
}
}
else{
node->visited = NONE;
printf("%d\n", node->val);
}
}
}
A trick to make things with a single stack it self.
1. Push all the left nodes till you encounter null.
while(stack is not empty)
pop the first element.
if popped element is dummy (I 'll explain the logic behind this), then pop the next
element and print it out.
if the popped element does not have a right child, print it out
if the popped element has a right child
then
a) push the popped element, and a dummy node. This dummy node indicates that we
should print whatever node that sits below this node on stack, which would be the prior pushed node. This is to indicate that a node has a right child and should only be printed (and not re-evaluated for the presence of right tree) when later that node is encountered on the stack.
b) push the right child
b) push all the element to the left of this right child.
end while
And the code:
public void postOrderTraversal(Node node) {
if (node == null) {
return;
}
Node dummy = new Node();
LinkedList<Node> list = new LinkedList<Node>();
list.add(node);
while (node.left != null) {
list.add(node.left);
node = node.left;
}
while (!list.isEmpty()) {
Node popped = list.removeLast();
if (popped == dummy) {
System.out.println(list.removeLast().data);
} else if (popped.right == null) {
System.out.println(popped.data);
} else {
list.add(popped);
list.add(dummy);
Node rightTree = popped.right;
list.add(rightTree);
while (rightTree.left != null) {
list.add(rightTree.left);
rightTree = rightTree.left;
}
}
}
}
public void printPostOrderNR() {
BinarayTreeNode node = root;
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();
if(node != null)
stack.push(node);
while (stack.isempty() == false){
node = stack.peek();
if(node.getVisited()) {
stack.pop();
node.print();
}
else {
node.setVisited();
right = node.getRight();
if(right != null) stack.push(right);
left = node.getLeft();
if(left != null) stack.push(left);
}
}
struct{
mynode *node;
unsigned vleft :1; // Visited left?
unsigned vright :1; // Visited right?
}save[100];
/ Iterative Postorder
void iterativePostorder(mynode *root)
{
int top = 0;
save[top++].node = root;
while ( top != 0 )
{
/* Move to the left subtree if present and not visited */
if(root->left != NULL && !save[top].vleft)
{
save[top].vleft = 1;
save[top++].node = root;
root = root->left;
continue;
}
/* Move to the right subtree if present and not visited */
if(root->right != NULL && !save[top].vright )
{
save[top].vright = 1;
save[top++].node = root;
root = root->right;
continue;
}
printf("[%d] ", root->value);
/* Clean up the stack */
save[top].vleft = 0;
save[top].vright = 0;
/* Move up */
root = save[--top].node;
}
}
two stack solution will work with lil modification
1. Initially push the root into stack1.
2. while stack1 is not empty pop one element from stack1 and push into stack2 and push its left and right child into stack1
3. pop elements in stack2 will give the postorder
- sindhu August 20, 2009