Latest From My Blog

Showing posts with label traversal. Show all posts
Showing posts with label traversal. Show all posts

Algorithm: Inorder Tree Traversal without Recursion

Its been a long time since I'd posted something about programming and algorithms. I've been reading a lot more about algorithms, so found one perfectly explained article, thought I should share it with you people.

Using Stack is the obvious way to traverse tree without recursion. Below is an algorithm for traversing binary tree using stack.
See this for step wise step execution of the algorithm.

1) Create an empty stack S.
2) Initialize current node as root
3) Push the current node to S and set current = current->left until current is NULL
4) If current is NULL and stack is not empty then
     a) Pop the top item from stack.
     b) Print the popped item, set current = current->right
     c) Go to step 3.
5) If current is NULL and stack is empty then we are done.

Let us consider the below tree for example:

            1
          /   \
        2      3
      /  \
    4     5

Step 1 Creates an empty stack: S = NULL

Step 2 sets current as address of root: current -> 1

Step 3 Pushes the current node and set current = current->left until current is NULL
     current -> 1
     push 1: Stack S -> 1
     current -> 2
     push 2: Stack S -> 2, 1
     current -> 4
     push 4: Stack S -> 4, 2, 1
     current = NULL

Step 4 pops from S
     a) Pop 4: Stack S -> 2, 1
     b) print "4"
     c) current = NULL /*right of 4 */ and go to step 3
Since current is NULL step 3 doesn't do anything.

Step 4 pops again.
     a) Pop 2: Stack S -> 1
     b) print "2"
     c) current -> 5/*right of 2 */ and go to step 3

Step 3 pushes 5 to stack and makes current NULL
     Stack S -> 5, 1
     current = NULL

Step 4 pops from S
     a) Pop 5: Stack S -> 1
     b) print "5"
     c) current = NULL /*right of 5 */ and go to step 3
Since current is NULL step 3 doesn't do anything

Step 4 pops again.
     a) Pop 1: Stack S -> NULL
     b) print "1"
     c) current -> 3 /*right of 5 */

Step 3 pushes 3 to stack and makes current NULL
     Stack S -> 3
     current = NULL

Step 4 pops from S
     a) Pop 3: Stack S -> NULL
     b) print "3"
     c) current = NULL /*right of 3 */

Traversal is done now as stack S is empty and current is NULL.

Implementation:


#include<stdio.h>
#include<stdlib.h>
#define bool int

/* A binary tree tNode has data, pointer to left child
   and a pointer to right child */
struct tNode
{
   int data;
   struct tNode* left;
   struct tNode* right;
};

/* Structure of a stack node. Linked List implementation is used for
   stack. A stack node contains a pointer to tree node and a pointer to
   next stack node */

struct sNode
{
  struct tNode *t;
  struct sNode *next;
};

/* Stack related functions */
void push(struct sNode** top_ref, struct tNode *t);
struct tNode *pop(struct sNode** top_ref);
bool isEmpty(struct sNode *top);

/* Iterative function for inorder tree traversal */
void inOrder(struct tNode *root)
{
  /* set current to root of binary tree */
 struct tNode *current = root;
  struct sNode *s = NULL;  /* Initialize stack s */
  bool done = 0;
  while (!done)
  {
    /* Reach the left most tNode of the current tNode */
    if(current !=  NULL)
    {
      /* place pointer to a tree node on the stack before traversing
        the node's left subtree */
      push(&s, current);                                              
      current = current->left; 
    }      
    /* backtrack from the empty subtree and visit the tNode
       at the top of the stack; however, if the stack is empty,
      you are done */
    else                                                            
    {
      if (!isEmpty(s))
      {
        current = pop(&s);
        printf("%d ", current->data);

        /* we have visited the node and its left subtree.
          Now, it's right subtree's turn */
        current = current->right;
      }
      else
        done = 1;
    }
  } /* end of while */
}    

/* UTILITY FUNCTIONS */

/* Function to push an item to sNode*/
void push(struct sNode** top_ref, struct tNode *t)
{
  /* allocate tNode */
  struct sNode* new_tNode =
            (struct sNode*) malloc(sizeof(struct sNode));
  if(new_tNode == NULL)
  {
     printf("Stack Overflow \n");
     getchar();
     exit(0);
  }           
  /* put in the data  */
  new_tNode->t  = t;
  /* link the old list off the new tNode */
  new_tNode->next = (*top_ref);  

  /* move the head to point to the new tNode */
  (*top_ref)    = new_tNode;
}

/* The function returns true if stack is empty, otherwise false */
bool isEmpty(struct sNode *top)
{
   return (top == NULL)? 1 : 0;
}  
/* Function to pop an item from stack*/

struct tNode *pop(struct sNode** top_ref)
{
  struct tNode *res;
  struct sNode *top;

  /*If sNode is empty then error */
  if(isEmpty(*top_ref))
  {
     printf("Stack Underflow \n");
     getchar();
     exit(0);
  }
  else
  {
     top = *top_ref;
     res = top->t;
     *top_ref = top->next;
     free(top);
     return res;
  }
}

/* Helper function that allocates a new tNode with the
   given data and NULL left and right pointers. */
struct tNode* newtNode(int data)
{
  struct tNode* tNode = (struct tNode*)
                       malloc(sizeof(struct tNode));
  tNode->data = data;
  tNode->left = NULL;
  tNode->right = NULL;

  return(tNode);
}

/* Driver program to test above functions*/
int main()
{

  /* Constructed binary tree is

            1

          /   \

        2      3

      /  \

    4     5

  */
  struct tNode *root = newtNode(1);
  root->left        = newtNode(2);
  root->right       = newtNode(3);
  root->left->left  = newtNode(4);
  root->left->right = newtNode(5);

  inOrder(root);

  getchar();
  return 0;
}

Time Complexity: O(n)

This article has been shared from Geeks for Geeks. Please let me know if you have any concern about anything in this article.

Later folks.... :)

Programming: Validate All Parenthesis in an Expression

Today, I am going to share one article about parenthesis validation in an expression. This can also be applied to a string containing parenthesis. So here we go.

Given an expression string exp, write a program to examine whether the pairs and the orders of “{“,”}”,”(“,”)”,”[","]” are correct in exp. For example, the program should print true for exp = “[()]{}{[()()]()}” and false for exp = “[(])”

Algorithm:
1) Declare a character stack S.
2) Now traverse the expression string exp.
    a) If the current character is a starting bracket (‘(‘ or ‘{‘ or ‘[') then push it to stack.
    b) If the current character is a closing bracket (')' or '}' or ']‘) then pop from stack and if the popped character is the matching starting bracket then fine else parenthesis are not balanced.
3) After complete traversal, if there is some starting bracket left in stack then “not balanced”

Implementation:

#include<stdio.h>
#include<stdlib.h>
#define bool int

/* structure of a stack node */
struct sNode
{
   char data;
   struct sNode *next;
};

/* Function to push an item to stack*/
void push(struct sNode** top_ref, int new_data);

/* Function to pop an item from stack*/
int pop(struct sNode** top_ref);

/* Returns 1 if character1 and character2 are matching left
   and right Parenthesis */
bool isMatchingPair(char character1, char character2)
{
   if(character1 == '(' && character2 == ')')
     return 1;
   else if(character1 == '{' && character2 == '}')
     return 1;
   else if(character1 == '[' && character2 == ']')
     return 1;
   else
     return 0;
}

/*Return 1 if expression has balanced Parenthesis */
bool areParenthesisBalanced(char exp[])
{
   int i = 0;
   /* Declare an empty character stack */
   struct sNode *stack = NULL;
   /* Traverse the given expression to check matching parenthesis */
   while(exp[i])
   {
      /*If the exp[i] is a starting parenthesis then push it*/
      if(exp[i] == '{' || exp[i] == '(' || exp[i] == '[')
        push(&stack, exp[i]);

      /* If exp[i] is a ending parenthesis then pop from stack and
          check if the popped parenthesis is a matching pair*/
      if(exp[i] == '}' || exp[i] == ')' || exp[i] == ']')
      {
          /*If we see an ending parenthesis 
   without a pair then return false*/
         if(stack == NULL)
           return 0;

         /* Pop the top element from stack, if it is not a pair
            parenthesis of character then there is a mismatch.
            This happens for expressions like {(}) */

         else if ( !isMatchingPair(pop(&stack), exp[i]) )
           return 0;
      }
      i++;
   }
    
   /* If there is something left in 
   expression then there is a starting
      parenthesis without a closing parenthesis */
   if(stack == NULL)
     return 1; /*balanced*/
   else
     return 0;  /*not balanced*/
}
/* UTILITY FUNCTIONS */
/*driver program to test above functions*/

int main()
{
  char exp[100] = "{()}[]";
  if(areParenthesisBalanced(exp))
    printf("\n Balanced ");
  else
    printf("\n Not Balanced ");  \
  getchar();
}   


/* Function to push an item to stack*/
void push(struct sNode** top_ref, int new_data)
{
  /* allocate node */
  struct sNode* new_node =
            (struct sNode*) malloc(sizeof(struct sNode));
  if(new_node == NULL)
  {
     printf("Stack overflow \n");
     getchar();
     exit(0);
  }          

  /* put in the data  */
  new_node->data  = new_data;

  /* link the old list off the new node */
  new_node->next = (*top_ref); 

  /* move the head to point to the new node */
  (*top_ref)    = new_node;
}

/* Function to pop an item from stack*/
int pop(struct sNode** top_ref)
{
  char res;
  struct sNode *top;

  /*If stack is empty then error */
  if(*top_ref == NULL)
  {
     printf("Stack overflow \n");
     getchar();
     exit(0);
  }
  else
  {
     top = *top_ref;
     res = top->data;
     *top_ref = top->next;
     free(top);
     return res;
  }
}

Time Complexity: O(n)
Auxiliary Space: O(n) for stack.

Hope it helps. This article has been shared from Geeks for Geeks.
..... Next Time :)

Binary Tree Traversal: Pre-order, in-order and post-order

Hello to one and all,

Today I leant about binary tree traversal. First of all let me quickly tell you what is binary tree.

Binary tree is a tree data structure in which each node has at most two child nodes i.e. left child node and right child node.

For more about binary tree read this wiki.

And one more thing, for those who don't know what is traversal.
Traversal of tree is the process of visiting each node of the tree data structure exactly once in some systematic way.

Ok. So consider following binary tree for tree traversal explanation.

Binary Tree Traversal: Pre-order, in-order and post-order
Binary Tree

(1) Pre-order Traversal:
Pre-order traversal is followed by this process: (a) Visit the root of the tree, (b) visit the left sub tree of the root, (c) visit the right sub tree of the root.

Follow this process and you'll be having pre-order traversal as a result. Here we are dividing left node and right node of the root as sub trees. Then again we will follow the process of dividing until we reach leaf node of the sub tree.

Pre-order of given tree is: 7, 1, 0, 3, 2, 5, 4, 6, 9, 8, 10

(2) In-order Traversal:
In-order traversal is followed by this process: (a) Visit the left sub tree of the root, (b) visit the root of the binary tree, (c) visit the right sub tree of the root.

When you visit left sub tree of the root, in our case of the binary tree, 1 will become root for the sub tree and the above process will be repeated until we reach leaf node in the sub-sequent sub trees.

In-order Traversal of given tree is: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

(3) Post-order Traversal:
Post-order traversal is followed by this process: (a) Visit the left sub tree of the root node, (b) Visit the right sub tree of the root node, (c) Visit the root of the binary tree.

Post-order traversal of given tree is: 0, 2, 4, 6, 5, 3, 1, 8, 10, 9, 7

Please correct me if I am wrong somewhere. Hope it helps.

I have read this article on This Website.

Keep learning. Keep Sharing. Keep Improving.
.....Next Time..:)


+