Right view of a binary tree
December 7, 2017
Count number of zeros in a Row-wise Col-wise sorted binary matrix
December 29, 2017

Iterative pre-order traversal using stack

We have seen the in-order traversal of a binary tree. It is a recursive code. Recursion stack can be simulated using an explicit Stack data structure and keeping the function non-recursive. Let us see how:
When a function calls itself, its activation record (stack frame) is pushed in the function call stack of memory. The function call stack can be simulated using an extra stack. This logic can be used to convert any recursive implementation to non-recursive.
Take a Stack data structure and push contents of activation record (stack frame) of a function into that stack and simulate the recursion. Let us see the recursive function to print pre-order traversal of a binary tree again

void preOrder(Node*r)
{
  if(r==NULL){ return; } // TERMINATING CONDITION
  
  cout<<r->data<<" ";  
  preOrder(r->left);
  preOrder(r->right);
}

Here we are printing the data at the root and doing the preorder traversal of left subtree, followed by pre-order traversal of right subtree. In a way, after printing the root, we follow the left subtree and when recursion returns to the root again, we call it for right sub-tree.
This can be done by proceeding with the left subtree while pushing the right subtree in stack. After we are done with the left subtree, pop the stack and traverse that subtree.

void preOrderStack(Node*r)
{
  if (r == NULL) return;
  Stack s;
  while(r != NULL)
  {
    cout<< r->data<<" ";
    if(r->left == NULL)
      r = s.pop();
    else
    {
      if(r->right != NULL) // PUSH RIGHT CHILD FOR LATER
        s.push(r->right);
      r = r->left;
    }
  }
}

Asymptotic time taken by both the functions is O(n), but preOrderStack takes less time than the previous one. Below is the complete code in C++

#include <iostream>
using namespace std;
// TREE NODE
struct Node{
  int data;
  Node* left;
  Node* right;
  Node(int x):data(x), left(NULL), right(NULL){}
};
//STACK IMPLEMENTATION
class Stack
{
  // NODE OF A LINKED LISTs
  struct SNode{
    Node* data;
    SNode* next;
    // CONSTRUCTORS
    SNode():data(NULL), next(NULL){}
    SNode(Node* v):data(v), next(NULL){}
  };
  SNode* top;
public:
  Stack():top(NULL){} // DEFAULT CONSTRUCTOR. top = NULL
  void push(Node* x);
  Node* pop();
  bool isEmpty();
};
void Stack::push(Node* x){
  SNode* temp = new SNode(x);
  temp->next = top;
  top = temp;
}
Node* Stack::pop(){
  if(isEmpty()) // STACK EMPTY
  {
    cout<<"STACK EMPTY";
    return NULL;
  }
  else{
    // REMOVE THE FIRST NODE
    Node* value = top->data;
    SNode* temp = top;
    top = top->next;
    delete temp;
    return value;
  }
}
bool Stack::isEmpty(){
  return (top == NULL);
}
void preOrder(Node*r)
{
  if(r==NULL){ return; } // TERMINATING CONDITION
  cout<<r->data<<" ";
  preOrder(r->left);
  preOrder(r->right);
}
void preOrderStack(Node*r)
{
  if (r == NULL) return;
  Stack s;
  while(r != NULL)
  {
    cout<< r->data<<" ";
    if(r->left == NULL)
      r = s.pop();
    else
    {
      if(r->right != NULL) // PUSH RIGHT CHILD FOR LATER
        s.push(r->right);
      r = r->left;
    }
  }
}
int main()
{
  Node *r = new Node(5);
  r->left = new Node(3);
  r->right = new Node(20);
  r->left->left = new Node(1);
  r->left->right = new Node(4);
  r->right->left = new Node(15);
  r->right->right = new Node(25);
    r->right->right->left = new Node(13);
    r->right->right->right = new Node(17);
  preOrder(r);  cout<<endl;
  preOrderStack(r);  cout<<endl;
  return 0;
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *