Ad

Sunday 30 June 2013

Algo#30: Iterative implementation of Post-order, Pre-order & In-order traversal of given binary tree

We mostly use recursive function whenever we are asked traversal of binary tree. But what if you have to do it iterative. All recursion function can be converted to iterative with more or less effort.

Here we will see Post-order, Pre-order & In-order traversal of given binary tree using iterative method.

Following is implementation of above problem in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Saturday 29 June 2013

Algo#29: Check whether given number's bit representation is palindrome or not.

To find whether anything is palindrome or not,easiest method is to reverse it and check whether it is same as original. We will follow same approach for checking whether given number's bit representation is palindrome or not.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Friday 28 June 2013

Algo#28: Help frog to cross river.

Lets say there is a river that is η meters wide. At every meter from the starting shore, there may or may not be a stone enough for frog to sit. Now a frog needs to cross the river. However the frog has the limitation that if it has just jumped x meters, then it can take next jump only of size  x-1, x or x+1 meters. First jump can be of only 1 meter when starting from shore.

Assume frog can see all stone from this shore to opposite shore. Can frog determine whether it can make it to the other end or not.

Following is implementation of above problem in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Thursday 27 June 2013

Algo#27: Count number of 1's in given number

Brute force method to count number of 1's in given number is to iterate through each bit and check if it is 1, then increment counter. But it will take 32 checks (assuming 32 bit number).

Can we do better? Is there any way by which we don't need to check all bits? What if we iterate as many times as numbers of 1's. To achieve it, we have to remove 1 from number at each iteration, then only at last when no one is remaining in number, we can stop.

Manipulation of bits in number is only solution to reduce iteration. By doing x-1, we can eliminate last 1 from given number but it will introduce tailing 1's in number. But those should be not an issue for us. Because we have AND weapon to get rid of all tail 1's.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Wednesday 26 June 2013

Algo#26: Binary Search In Unbounded Array

Binary Search in Unbounded array.

Following is simple algorithm for above problem.
Step 1: Locate lower and upper bound using jump at every 2^k location
Step 2: Do binary search within located bounds.

Following is implementation of above algorithm in c++ language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Tuesday 25 June 2013

Algo#25: Find kth smallest from given 2 sorted array.

Finding kth smallest element from given 2 sorted array is not big deal if we are allowed to do it in O(K) or O(N+M). But what if you are asked to do it less than that. Can we use binary search technique to reduce complexity as given array are sorted !!

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Monday 24 June 2013

Algo#24: Find min and max from given array.

Given problem of finding min and max from given array seems to be very trivial problem. But what if you are asked to do it in less than 2N-3 comparisons!

Following is simple algorithm for above problem.
Step 1: Partition given array in 2 parts.
        1.1: Compare 2 element pairs for all elements.
        1.2: Put min out of this 2 elements in list-1 and max out of this 2 elements in list-2.
Step 2: Find min & max from partial lists.
        2.1: Find running min from list-1.
        2.2: Find running max from list-2.

Though at first look, given algorithm seems to have other 2N space for storing partial list with 3N/2 -1 comparisons to find min & max. But making twist during implementation can make above algorithm to run in O(1) space complexity and 3N/2+3 comparisons only.
.
Following is implementation of above algorithm in c language with twist to reduce space complexity.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Sunday 23 June 2013

Algo#23 Search given key in BST, if not present return next higher value than key which is present

Search given key in BST, if not present return next higher value than key which is present.

If we think just for a while, we will come to know that it is nothing but modified search in BST only. We have to maintain node when ever we are taking left turn in BST. Thats it. Done. Why it will work like this? Because if we are going right side, it means our key is grater than value at current node. So we don't need that value which is less than our key.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Saturday 22 June 2013

Algo#22: Swap nibbles of number.

Nibbles are nothing but chunk of 4 bits in simple language.

To swap nibbles in given number, we have to extract 4-bits chunk from number and depending on system, we have to shift them accordingly.

Following is implementation of above algorithm in c language for 8-bit system ( Imaginary ).





Please write comments if you find anything wrong or you want to add something more related to this topic.

Friday 21 June 2013

Algo#21: Give next higher boundary number.

To give next higher boundary of number, is used when allocating memory to structure, so that access to its members are fast.


Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Thursday 20 June 2013

Algo#20: Tail command implementation

Tail command is used for extracting last n lines from file. This is very common question that we can expect  in any IT interview. To implement tail command we will use queue data structure. 

Following is simple algorithm for tail command implementation with n as parameter (number of last lines to read).
Step 1: Read line from file, and store it into queue.
Step 2: If number of lines in queue exceeds parameter n, then we can delete one line from front. Because we only need to keep n lines in queue.
Step 3: When file reading ends, we have n lines in queue.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Wednesday 19 June 2013

Algo#19: Convert given number in different endian system than your system.

There are mainly two types of system based on endianness available to us.
1) Big endian
2) Little endian

To convert one number other endianness system, we have to change order of all bytes.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Tuesday 18 June 2013

Algo#18: Add two numbers without using plus(+) operator.

There are many ways to do one thing. Given problem very well follows it. This kind of problems will test how much comfortable you are with concepts as well as language. Because both will improve your skills to solve problem in more than one way.

There is no single algorithm for such tricks. Practice makes (wo)man perfect.

Following is implementation of some of the tricks in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Monday 17 June 2013

Algo#17: Check whether array is sorted or not using recursion

This program basically test your recursion skills. So what should be our approach when questions like this comes.

When we are solving any problem with recursion, we have to identify datum which we are going to process in one iteration of recursion. Here in our case, we will process one element of array at a time, it means remaining n-1 element should be process by recursion.

Following is simple recursive algorithm for Checking array for sorted property using recursion.
Step 1: If we are having only one element, then by default it is sorted. Success.
Step 2: Otherwise, relationship between first and second element. first element <= second element. If not then failure, else go to step 3.
Step 3: Get success or failure indicator for remaining array of n-1 element using recursion.If remaining array comes out to be sorted, then whole array is sorted.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Sunday 16 June 2013

Algo#16: Solve 8-Queen Problem.

8-Queen problem ask us to set 8 queen on board such that they don't attack each other by any direction. We must be knowing that queen can move row wise, column wise and in both diagonals also.

First thing we need here is, way to check whether we can put chosen queen at particular location or not. We can put queen only if satisfy following criteria.
1. It should be unique in its row.
2. It should be unique in its column.
3. It should be unique in its both diagonals.

Lets say we made some function called Check() which tell whether current queen have any conflicts with previous queens that we have set. Now we are ready to take up our back tracking algorithm.

Following is simple algorithm for finding 8-Queen Problem.
Step 1: If we have filled all rows of board than we are done.
Step 2: Otherwise try all possible columns for current queen and check if it has any conflicts with any previous queen, if not then set remaining queens.

Following is implementation of above algorithm in c language.




Please write comments if you find anything wrong or you want to add something more related to this topic.

Saturday 15 June 2013

Algo#15: Sudoku solver

To solve given Sudoku of any level, by back tracking method, we have to try each possible combinations until it gets solved. We have to take care about given filled numbers which we can not modified while doing back track.

First thing we need here is, way to check whether we can put chosen number at particular location or not. We can put number only if satisfy following criteria.
1. It should be unique in its row.
2. It should be unique in its column.
3. It should be unique in its region (3 * 3) box.

Lets say we made some function called isValid() which tell check above constraint for our move. Now we are ready to take up our back tracking algorithm.

Following is simple recursive algorithm for Solving given Sudoku.
Step 1: If we have filled all position without violation of any constraint, then we are done.
Step 2: If current location (filling row by row, left to right) is fixed location, we can not modified it, go ahead and fill remaining location recursively.
Step 3: Try every element from 1 to 9 one by one and check if remaining Sudoku can be solved recursively. If we are out of all nine numbers, and Sudoku doesn't yet solved then Sudoku is unsolvable.

Following is implementation of above algorithm in c language.




Please write comments if you find anything wrong or you want to add something more related to this topic.

Friday 14 June 2013

Algo#14: Set specified bits range in number.

Set specified bits range in number.

Following is simple algorithm for setting bits range in given number.
Step 1: Make mask for start index to end index.
        1.1: First step to make mask is, set 1 in each position from 0 to end index, call it mask-1.
        1.2: Then same way, set 1 in each position from 0 to start index, call  it mask-2.
        1.3: XOR mask-1 and mask-2, which will give us our desired mask having 1 set from start to end index.
Step 2: Do OR operation between given number and mask.

Following is implementation of above algorithm in c language in 1 line.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Thursday 13 June 2013

Algo#13: Cyclic right shift of bits in number

Manipulation of bits are very crucial if you can apply it properly in your computing because it is one of the fastest technique for computing.

Following is simple algorithm for finding Cyclic Right Shift of bits in given number by S bits.

Step 1: Take right S bits of number, and shift it right by R-S positions, where R is number of total bits in given number, call it Partial-1.
Step 2: Take left R-S bits of number, and shift it left by S positions, call it Partial-2.
Step 3: Do OR operation between Partial-1 and Partial-2.

Following is implementation of above algorithm in c language in one line.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Wednesday 12 June 2013

Algo#12: Binary Search Technique with Duplicates - Find Last Occurrence Index

Binary search technique is very well known for its fast search result provided given array is sorted.

Following is simple iterative algorithm for Binary Search (Last Occurrence) in Sorted Array With Duplicates.
Step 1: Set l(left) at start index of array.
Step 2: Set r(right) at end index of array.
Step 3: Set left-border at start index of array.
Step 4: Set right-border at end index of array.
Step 5: Repeat following until r>=l
        5.1: Initialize mid using current left and right index (l+(r-l)/2).
      5.2: If element at mid index is target element and element at after mid index is different than target element, then return mid index as successful binary search.
        5.3: Otherwise if element at mid index is greater or equal to target element, then replace r = mid -1
        5.4: Otherwise if element at mid index is less than target element, then replace l = mid +1
Step 6: If you reach here, element you are searching for is not found.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Tuesday 11 June 2013

Algo#11: Binary Search Technique with Duplicates - Find First Occurrence Index

Binary search technique is very well known for its fast search result provided given array is sorted.

Following is simple iterative algorithm for Binary Search (First Occurrence) in Sorted Array With Duplicates.
Step 1: Set l(left) at start index of array.Step 2: Set r(right) at end index of array.
Step 3: Set left-border at start index of array.
Step 4: Set right-border at end index of array.
Step 5: Repeat following until r>=l
        5.1: Initialize mid using current left and right index (l+(r-l)/2).
      5.2: If element at mid index is target element and element at before mid index is different than target element, then return mid index as successful binary search.
        5.3: Otherwise if element at mid index is greater or equal to target element, then replace r = mid -1
        5.4: Otherwise if element at mid index is less than target element, then replace l = mid +1
Step 6: If you reach here, element you are searching for is not found.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Monday 10 June 2013

Algo#10: Binary Search Technique

Binary search technique is very well known for its fast search result provided given array is sorted.

Following is simple iterative algorithm for Binary Search in Sorted Array.
Step 1: Set l(left) at start index of array.
Step 2: Set r(right) at end index of array.
Step 3: Repeat following until r>=l
        3.1: Initialize mid using current left and right index (l+(r-l)/2).
        3.2: If element at mid index is target element, then return mid index as successful binary search.
        3.3: Otherwise if element at mid index is greater than target element, then replace r = mid -1
        3.4: Otherwise if element at mid index is less than target element, then replace l = mid +1
Step 4: If you reach here, element you are searching for is not found.
Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Sunday 9 June 2013

Algo#9: Add 2 numbers represented by linked list such that MSD of number is head of linked list.

Numbers represented by link list means each digit of number is occupying 1 node in linked list. Obviously your next question would be how number is stored, is it head to tail or tail to head in linked list. Both ways are right depending on purpose of your application. Lets say, Most Significant Digit (MSD) is representing head of linked list. E.G 321 can be represented as : 3->2->1 , 52 can be represented as : 5->2

So coming to given problem. We have been given 2 such linked list, and our task at hand is to sum up these 2 numbers and store its addition in one such link list. One thing to note here is, when list are represented like this, actually we are having tough problem to solve because 2 list can be of different size. One way to convert this problem in easy one is by reversing both list, then apply algorithm of adding list when header represent LSD. But what if we have been asked that we can't modify given 2 list at all. Here comes recursion to help us.

Following is simple recursive algorithm for adding  2 numbers represented by linked list such that MSD of number is head of linked list. Technique same as post order traversal, process remaining (child) list first before adding current node.

Assume that size(first list) >= size(second list) , this assumption can be taken without any loss of generality of our algorithm because we can always pass list to our algorithm such that assumption is perfectly valid.

Step 1: If both current list are empty, then resultant list is also empty.
Step 2: Otherwise, any one or both list are not empty.
        2.1: Make new resultant list node with its value as zero.
      2.2: Add remaining digits from both list recursively same way. Don't forget to get carry of remaining addition.
           2.2.1: If both list have same size, then add digit from first list, digit from second list and carry of remaining list addition.
          2.2.2: If size(first list) > size(second list), then add digit from first list and carry of remaining list addition.
       2.3: Get resultant digit of this addition by taking modulo 10 and put it inside newly created node.
       2.4: Attach list built from recursion to current resultant list.
       2.5: [CRITICAL STEP] Fill reverse carry so that previous iteration can use it.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Saturday 8 June 2013

Algo#8: Add 2 numbers represented by linked list such that LSD of number is head of linked list.

Numbers represented by link list means each digit of number is occupying 1 node in linked list. Obviously your next question would be how number is stored, is it head to tail or tail to head in linked list. Both ways are right depending on purpose of your application. Lets say, Least Significant Digit (LSD) is representing head of linked list. E.G 321 can be represented as : 1->2->3

So coming to given problem. We have been given 2 such linked list, and our task at hand is to sum up these 2 numbers and store its addition in one such link list.

Following is simple algorithm for adding  2 numbers represented by linked list such that LSD of number is head of linked list.

Step 1: If both current list are empty, then resultant list is also empty.
Step 2: Otherwise, any one or both list are not empty.
        2.1: Make new resultant list node with its value as zero.
        2.2: Add initial digit from both current list (Add zero if any list is empty), along with carry from previous addition (if any else add zero).
        2.3: Get resultant digit of this addition by taking modulo 10 and put it inside newly created node and keep carry ready to be passed to next iteration.
       2.4: Add remaining digits from both list recursively same way. Don't forget to pass carry of last addition.
       2.5: Attach list built from recursion to current resultant list node.

Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Friday 7 June 2013

Algo#7: Closest Value Search in Binary Search Tree (BST)

Closest Value Search in Binary Search Tree (BST) means returning nearest value in BST to given key.

Following is simple algorithm for finding Closest Value in BST.
Step 1: Current root itself is NULL, then closest value is zero.
Step 2: If current root matches target key value, then closest value is key itself.
Step 3: Otherwise, consider current root as closest value and do following.
        3.1: If key is smaller then current root, find closest value on left side tree of current root recursively and call it RecursiveClosest.
        3.2: If key is larger then current root, find closest value on right side tree of current root recursively and call it RecursiveClosest.
Step 4: Return current root or RecusiveClosest depending on which ever is nearer to target key.


Following is implementation of above algorithm in c language.





Please write comments if you find anything wrong or you want to add something more related to this topic.

Thursday 6 June 2013

Algo#6: Preorder Successor in Binary Tree

Preorder Successor value for any node X means value of node Y that comes just after node X while doing Preorder traversal. For given tree in figure, preorder traversal (Root Left Right) would be : 1 2 4 5 3 6. We can search preorder successor for any node by just looking at this traversal output. E.G. preorder successor of node '3' is node '6' because '6' appears after '3' in given traversal.

But in real life we encounter Preorder Successor to be search for any node randomly, and if we go by this method of doing preorder traversal first then giving successor, it would be inefficient because of its time complexity of O(n) in large trees. So we need some method which can return Preorder Successor randomly for any node without doing traversal explicitly in less time complexity.

Luckily preorder traversal follows some pattern which can help us in giving Preorder Successor for any node without doing traversal at all.

Following is simple algorithm for finding Preorder Successor of binary tree.
Step 1: Current root itself is NULL, then successor is also NULL.
Step 2: Current root contains value same as key for which we are looking successor.
        2.1: Current root has right child, then left most node of right child is successor.
        2.2: Current root does have right child r, then r is successor.
        2.3: Current root is left leaf node and having sibling on right side
        2.4: Otherwise, if current root has an ancestor, v, which is a left-child and v has a right sibling, vrs, then succ(current root) is vrs
        2.5: If none of above applies, then succ(current root) doesn't exist.
Step 3: Current root is not the target node for which we are looking successor.
        3.1: Search target node and its successor in left side of tree recursively, and return if found.
        3.2: Search target node and its successor in right side of tree recursively, and return.

Following is implementation of above algorithm in c language.




Please write comments if you find anything wrong or you want to add something more related to this topic.

Wednesday 5 June 2013

Algo#5: Preorder Predecessor in Binary Tree

Preorder Predecessor value for any node X means value of node Y that comes just before node X while doing Preorder traversal. For given tree in figure, preorder traversal (Root Left Right) would be : 1 2 4 5 3 6. We can search preorder predecessor for any node by just looking at this traversal output. E.G. preorder predecessor of node '4' is node '2' because '2' appears before '4' in given traversal.

But in real life we encounter Preorder Predecessor to be search for randomly any node, and if we go by this method of doing preorder traversal first then giving predecessor, it would be inefficient because of its time complexity of O(n) in large trees. So we need some method which can return Preorder Predecessor randomly for any node without doing traversal explicitly in less time complexity.

Luckily preorder traversal follows some pattern which can help us in giving Preorder Predecessor for any node without doing traversal at all.

Following is simple algorithm for finding Preorder Predecessor of binary tree.
Step 1: Current root itself is NULL, then predecessor is also NULL.
Step 2: Current root contains value same as key for which we are looking predecessor.
        2.1: If current root is the root of the tree, then pred(current root) is undefined
        2.2: If u has a left sibling, ls, then pred(current root) is the rightmost descendant of ls
        2.3: Otherwise, pred(current root) is parent(current root).
Step 3: Current root is not the target node for which we are looking predecessor.
        3.1: Search target node and its predecessor in left side of tree recursively, and return if found.
        3.2: Search target node and its predecessor in right side of tree recursively, and return.

Following is implementation of above algorithm in c language.



Please write comments if you find anything wrong or you want to add something more related to this topic.

Tuesday 4 June 2013

Algo#4: Postorder Successor in Binary Tree

Postorder Successor value for any node X means value of node Y that comes just after node X while doing Postorder traversal. For given tree in figure, postorder traversal (Left Right Root) would be : 4 5 2 6 3 1. We can search postorder successor for any node by just looking at this traversal output. E.G. postorder successor of node '4' is node '5' because '5' appears after '4' in given traversal.

But in real life we encounter Postorder Successor to be search for randomly any node, and if we go by this method of doing postorder traversal first then giving successor  it would be inefficient because of its time complexity of O(n) in large trees. So we need some method which can return Postorder successor randomly for any node without doing traversal explicitly in less time complexity.

Luckily postorder traversal follows some pattern which can help us in giving Postorder Successor for any node without doing traversal at all.

Following is simple algorithm for finding Postorder Successor of binary tree.
Step 1: If current root is NULL, then succ(current root) is NULL.
Step 2: If current root is target node for which we are looking for successor.
        2.1: If current root is the root of the tree, succ(current root) is undefined.
        2.2: Otherwise, if current root is a right child, succ(current root) is parent(current root).
        2.3: Otherwise current root is a left child and the following applies:
           2.3.1: If u has a right sibling, r, succ(current root) is the leftmost leaf in r's sub-tree
           2.3.2: Otherwise succ(current root) is parent(current root).
           2.3.3: If none of above applies, then succ(current root) doesn't exist.
Step 3: Current root is not the target node for which we are looking predecessor.
        3.1: Search target node and its predecessor in left side of tree recursively, and return if found.
        3.2: Search target node and its predecessor in right side of tree recursively, and return.

Following is implementation of above algorithm in c language.

/*
Algo#4: Postorder Successor in Binary Tree

Description: Find Postorder Successor value in given Biinary Tree.
*/
#include 
#include 

typedef struct node
{
    int data;
    struct node *left,*right;
} Node;

Node *leftmostLEAFnotNODE(Node *root)
{
    while (root->left || root->right)
    {
        if(root->left) root=root->left;
        else root=root->right;
    }

    return root;
}

Node *postorderSuccessorRec(Node *root, int key,Node *direct_parent, Node *parent,Node * treeroot)
{
    //Case 1: If current root is NULL, then succ(current root) is NULL.
    if (root==NULL)
        return 0;
    //Case 2: If current root is target node for which we are looking for successor.
    if (root->data == key)
    {
        //Case 2.1: If current root is the root of the tree, succ(current root) is undefined.
        if(root == treeroot)
            return NULL;
        //Case 2.2: Otherwise, if current root is a right child, succ(current root) is parent(current root).
        else if(direct_parent != NULL && direct_parent->right==root)
            return direct_parent;
        //Case 2.3: Otherwise current root is a left child and the following applies:

        //Case 2.3.1: If u has a right sibling, r, succ(current root) is the leftmost leaf in r's sub-tree
        else if(direct_parent != NULL && direct_parent->left==root && direct_parent->right!=NULL)
            return leftmostLEAFnotNODE(direct_parent->right);
        //Case 2.3.2: Otherwise succ(current root) is parent(current root).
        else if(direct_parent != NULL && direct_parent->left==root && direct_parent->right==NULL)
            return direct_parent;
        //Case 2.3.3: If none of above applies, then succ(current root) doesn't exist.
        else
            return NULL;
    }
    //Case 3: Current root is not the target node for which we are looking successor.
    else
    {
        //Case 3.1: Search target node and its successor in left side of tree recursively, and return if found.
        Node *left=postorderSuccessorRec(root->left,key,root,root,treeroot);
        if (left)
            return left;
        //Case 3.2: Search target node and its successor in right side of tree recursively, and return.
        return postorderSuccessorRec(root->right,key,root,parent,treeroot);
    }
}

Node *postorderSuccessor(Node *root, int key)
{
    return postorderSuccessorRec(root,key,NULL,NULL,root);
}

struct node* newNode(int data)
{
  struct node* node = (struct node*)  malloc(sizeof(struct node));
  node->data = data;
  node->left = NULL;
  node->right = NULL;

  return(node);
}


int main()
{

  /*
            1
          /   \
        2      3
      /  \    /
    4     5  6
  */
  struct node *root = newNode(1);
  root->left        = newNode(2);
  root->right       = newNode(3);
  root->left->left  = newNode(4);
  root->left->right = newNode(5);
  root->right->left = newNode(6);

  struct node * succ;
  succ = postorderSuccessor(root, 3);
  printf("Postorder Successor of %d is : %d\n",3,succ?succ->data:0);

  succ = postorderSuccessor(root, 4);
  printf("Postorder Successor of %d is : %d\n",4,succ?succ->data:0);

  getchar();
  return 0;
}



Please write comments if you find anything wrong or you want to add something more related to this topic.

Monday 3 June 2013

Algo#3: Postorder Predecessor in Binary Tree

Postorder Predecessor value for any node X means value of node Y that comes just before node X while doing Postorder traversal. For given tree in figure, postorder traversal (Left Right Root) would be : 4 5 2 6 3 1. We can search postorder predecessor for any node by just looking at this traversal output. E.G. postorder predecessor of node '5' is node '4' because '4' appears before '5' in given traversal.

But in real life we encounter Postorder Predecessor to be search for randomly any node, and if we go by this method of doing postorder traversal first then giving predecessor, it would be inefficient because of its time complexity of O(n) in large trees. So we need some method which can return Postorder Predecessor randomly for any node without doing traversal explicitly in less time complexity.

Luckily postorder traversal follows some pattern which can help us in giving Postorder Predecessor for any node without doing traversal at all.

Following is simple algorithm for finding Postorder Predecessor of binary tree.
Step 1: If current root is NULL, then pred(current root) is NULL.
Step 2: If current root is target node for which we are looking for predecessor.
        2.1: If current root has a right child, r, then pred(current root) is r.
        2.2: Otherwise If current root has a left child, l, then pred(current root) is l.
        2.3: Otherwise if current root has a left sibling, ls, then pred(current root) is ls
      2.4: Otherwise if current root has an ancestor, v, which is a right child and has a left sibling, vls, then pred(current root) is vls
        2.5: Otherwise, pred(current root) is undefined.
Step 3: Current root is not the target node for which we are looking predecessor.
        3.1: Search target node and its predecessor in left side of tree recursively, and return if found.
        3.2: Search target node and its predecessor in right side of tree recursively, and return.

Following is implementation of above algorithm in c language.




Please write comments if you find anything wrong or you want to add something more related to this topic.

Ad