1. Given the following output, draw the binary search tree. Inorder : EICFJBGDKHLA PreOrder : ABCEIFJDGHKL
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
    char val;
    struct node *left;
    struct node *right;
};
struct node *createnode(char ch)
{
    struct node *newnode =(struct node*) malloc(sizeof(struct node));
    newnode->val = ch;
    newnode->left = newnode->right = NULL;
    return newnode;
}
int findindex(char *inorder,char ch)
{
     int i;
     for(i=0;inorder[i]!=0&&inorder[i]!=ch;i++);
     return i;
}
struct node * constructNode(char *preorder,char *inorder,int instart,int inend)
{
    static int preindex = 0;
    if( instart>inend)
       return NULL;
 
    char ch = preorder[preindex++];
  /*  printf("ch is %c\n instart is %d inend is %d",ch,instart,inend);*/
    struct node * nd = createnode(ch);
    if(instart==inend)
       return nd;
    int l = strlen(inorder);
    int index = findindex(inorder,ch);
    struct node * left = constructNode(preorder,inorder,instart,index-1);
    struct node * right = constructNode(preorder,inorder,index+1,inend);
    nd->left = left;
    nd->right = right;
    return nd;
}
 
void inorderprint(struct node *nd)
{
  if(nd!=NULL)
  { 
    inorderprint(nd->left);
    printf("%c----->",nd->val);
    inorderprint(nd->right);
   }
}
int main()
{
    char inorder[30],preorder[30];
    struct node *root;
    printf("Enter inorder output");
    scanf("%s",inorder);
    printf("Enter preorder output");
    scanf("%s",preorder);
    root = constructNode(preorder,inorder,0,strlen(preorder)-1);
    printf("\n Inorder traversal is ");
    inorderprint(root);
}
2. Write an algorithm to add a new node non-recursively to a binary search tree and write a function for this.
NODEPTR insert_node_nr(NODEPTR nd,NODEPTR newnode)
{
     NODEPTR parent = nd;
     NODEPTR root = nd;
     if(root == NULL)
        return newnode;
    /*find a location add new node*/
     while(nd!=NULL)
     {
        parent = nd;
        if(newnode->val > nd->val)
            nd = nd->right;
        else if(newnode->val <nd->val)
           nd = nd->left;
        else
        {
               printf("Duplicate values not allowed");
               return NULL;
         }
     }
     if(newnode->val >parent->val)
         parent->right = newnode;
     else
         parent->left = newnode;
     return root;
}
int main()
{
      NODEPTR root = NULL;
      NODEPTR newnode;
    .....
     int n ;
     scanf("%d",&n);
     newnode = create_node(n);
     root = insert_node_nr(root,newnode);
  .....
}
3. Write algorithms for deleting a node from a binary search tree in all possible cases.
/* inorder successor is the minimum of 
right subtree*/
NODEPTR find_rightst_min(NODEPTR node)
{
     node = node->right;
     while(node->left!=NULL)
       node = node->left;
     return node;
}
NODEPTR delete_node(NODEPTR nd,int delval)
{
    if(nd==NULL)
       return nd;
    if(nd->val >delval)
        nd->left = delete_node(nd->left,delval);
     else if(nd->val < delval)
        nd->right = delete_node(nd->right,delval);
     else/*node found*/
     {
        if(nd->left==NULL && nd->right==NULL)/*leaf node*/
         {
             free(nd);
     	  nd = NULL;
         }
        else if(nd->left==NULL)/*has only right child*/
        {
           NODEPTR temp = nd->right;
           free(nd);
           nd =temp;
        }
        else if(nd->right==NULL)/*has only left child*/
        {
           NODEPTR temp = nd->left;
           free(nd);
           nd = temp;
        }
        else/*has both subtrees*/
         {
          NODEPTR min_node = find_rightst_min(nd);
          nd->val = min_node->val;
          nd->right = delete_node(nd->right,min_node->val);
         }      
      }
    return nd;  
}4. Explain one way and two way threaded binary trees
5. Draw a binary heap from the elements shown below. And also write a program to heap sort an array. 50 25 30 75 100 45 80
#include <stdio.h>
void printArray(int *arr,int n);
void swap(int *a,int *b)
{
     int temp = *a;
    *a = *b;
    *b = temp;
}
 
/* convert node at index i into a max heap */
void heapify(int arr[], int n, int i)
{     
    int largest = i;  
    int left = 2*i + 1;  /* left child = 2*i + 1*/
    int right = 2*i + 2;  /* right child = 2*i + 2*/
     
    if (left < n && arr[left] > arr[largest])
        largest = left;
   
    if (right < n && arr[right] > arr[largest])
        largest = right;
    
    if (largest != i)    {
        swap(&arr[i], &arr[largest]);        
        heapify(arr, n, largest);/*now node at largest may be out of order. heapify it*/
    }
}
void heapSort(int arr[], int n)
{
    int i;
    /* Build heap from array elements*/
    for ( i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);
 
    /*Extract 0th element (root) and move it at the end of array. Reduce the size of heap*/
    for ( i=n-1; i>=0; i--)
    {
        /* Move current root to end*/
        swap(&arr[0], &arr[i]);
        /* call max heapify on the reduced heap*/
        heapify(arr, i, 0);
    }
}
void readArray(int arr[], int n)
{
    int i;
    for ( i=0; i<n; ++i)
    {
        printf("a[%d]",i);
        scanf("%d",&arr[i]);
    }  
} 
void printArray(int arr[], int n)
{
    int i;
    for ( i=0; i<n; ++i)
        printf("%d ",arr[i]);
   printf( "\n");
}
 
int main()
{
    int arr[40];int n; 
    printf("What is array size");
    scanf("%d",&n);
    readArray(arr,n);
    
    heapSort(arr, n);
    printf("Sorted array is \n");
    printArray(arr, n);
}6. Write a function to find the number of leaf nodes in a given binary tree.
int count_leaf_nodes(NODEPTR nd)
{
    if(nd==NULL)
       return 0;
    if(nd->left ==NULL  && nd->right==NULL)
       return 1;
     
       return count_leaf_nodes(nd->left)+count_leaf_nodes(nd->right);
}7. Write a function to find in order successor of a given non-leaf node in a binary tree
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
        nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        in_order(nd->left);
        printf("%d---",nd->val);
        in_order(nd->right);
     }
}
NODEPTR search(NODEPTR nd,int num)
{
    while(nd!=NULL )
    {
        if (num > nd->val)
           nd = nd->right;
        else if (num< nd->val)
           nd = nd->left;
        else 
           return nd;
     }
     return NULL;/*not found*/
}
NODEPTR successor(NODEPTR root, NODEPTR nd)
{
     if(nd->right!=NULL)
     {
         nd = nd->right;
         while(nd->left!=NULL)
         { 
             nd = nd->left;
         }
         return nd;
     }
     else
     {
        NODEPTR succ = NULL;
        while(root!=NULL)
        {
            if(root->val > nd->val)
            {
                 succ = root;
        	root = root ->left;
            }
            else if(root->val <nd->val)
                root = root ->right;
            else
                return succ;
        }
        return root;
    } 
}
int main()
{
       NODEPTR root=NULL,delnode; 
       int n;
       do
       {
           NODEPTR newnode;
           printf("Enter value of node(-1 to exit):");
           scanf("%d",&n);
           if(n!=-1)
            {  
               newnode = create_node(n);
               root = insert_node(root,newnode);
             }
       } while (n!=-1); 
       printf("\nInorder traversal\n");
       in_order(root);  
       while(1)
       {   
         printf("Enter node value (-1 to stop):");
         scanf("%d",&n);
         if(n==-1)
            break;
         NODEPTR nd = search(root,n);
         if(nd==NULL)
             printf("%d is not present in tree",n);
         else
            {
             NODEPTR nds = successor(root,nd);
             if(nds!=NULL)
                printf("the successor is %d\n",nds->val);
             else
                printf("No successor\n");
            }
       }    
       return 0;
}8. Explain what is binary search tree with an example. Write a function to search a value in a binary search tree using iteration.
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
NODEPTR search_node(NODEPTR root, int num)
{
   NODEPTR temp = root;
   while(temp!=NULL)
   {
      if(temp->val>num)
         temp = temp->left;
      else if(temp->val<num)
         temp = temp->right;
      else/*we found a match*/
         return temp;
   }
   return NULL;/*no match*/
} 
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
        nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        in_order(nd->left);
        printf("%d---",nd->val);
        in_order(nd->right);
     }
}
int main()
{
       NODEPTR root=NULL,delnode; 
       int n;
       do
       {
           NODEPTR newnode;
           printf("Enter value of node(-1 to exit):");
           scanf("%d",&n);
           if(n!=-1)
            {  
               newnode = create_node(n);
               root = insert_node(root,newnode);
             }
       } while (n!=-1);
       
       printf("\nInorder traversal\n");
       in_order(root);
      
       while(1)
       {
          NODEPTR snode;
          printf("Enter value to search (-1 to quit):");
          scanf("%d",&n);
          snode = search_node(root,n);
          if(snode==NULL)
             printf("Value not found\n");
          else 
             printf("Value is found\n");
       }
       return 0;
}9. Write a function for inorder traversal of a threaded binary tree
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
   int isleftthread;
   int isrightthread;
};
typedef struct node *NODEPTR;
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     temp->isleftthread = 1;
     temp->isrightthread = 1;
     return temp;
}
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
     NODEPTR parent = nd;
     NODEPTR root = nd;
     if(root == NULL)
       return newnode;
     while(nd!=NULL)
     {
       parent = nd;
       if(newnode->val > nd->val)
       {
         if(nd->isrightthread)
         {
           nd = nd->right;
           break;
         }
         else
            nd = nd->right;	
       } 	
       else if(newnode->val <nd->val){
         if(nd->isleftthread)
 	 {
            nd = nd->left;
            break;
         }
         else
           nd = nd->left;
        }
        else
        {
           printf("Duplicate values not allowed");
           return NULL;
         }
     }
     if(newnode->val >parent->val)
	{/*insert as right child*/
	newnode->right = parent->right;
	parent->right = newnode;
	parent->isrightthread=0;
	newnode->left = parent;/*update thread*/
	}
     else
	{/*insert as left child*/
	newnode->left = parent->left;
 	parent->left = newnode;
	parent->isleftthread = 0;
	newnode->right = parent;/*update thread*/
	}
     return root;
}
void in_order(NODEPTR nd)
{
    /* find extreme left node*/
    while(!nd->isleftthread)
	nd = nd->left;
   /* traverse all nodes till extreme right end*/
    while(nd)
	{
	  printf("%d  ",nd->val);
	  if(nd->isrightthread)
             nd = nd->right;
          else 
            {/*find tree minimum of right subtree*/
              nd = nd->right;
              while(nd!=NULL && !nd->isleftthread)
                nd = nd->left;
           }
	} 
}
void pre_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        printf("%d---",nd->val);   
        pre_order(nd->left);
        pre_order(nd->right);
            
     }
} 
 
int main()
{
       NODEPTR root=NULL,delnode; 
       int n;
       do
       {
           NODEPTR newnode;
           printf("Enter value of node(-1 to exit):");
           scanf("%d",&n);
           if(n!=-1)
            {  
               newnode = create_node(n);
               root = insert_node(root,newnode);
             }
       } while (n!=-1);
       
       printf("\nInorder traversal\n");
       in_order(root);
       return 0;
}10. Given a binary tree, write a function to find the depth of a binary tree.
int find_height(NODEPTR nd)
{
   if(nd==NULL)
      return -1;
   else
     {
        int h1 = find_height(nd->left);
        int h2 = find_height(nd->right);
        h1 = h1>h2?h1:h2;/*maximum of heights of left subtree and right subtree */
        return  h1+1;
     }
}11. Write a function to print the nodes in ascending order of a binary tree
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        in_order(nd->left);
        printf("%d--->",nd->val);
        in_order(nd->right);
     }
}12. Write recursive functions for implementing tree traversal techniques - all of the three - inorder, preorder and postorder
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        in_order(nd->left);
        printf("%d--->",nd->val);
        in_order(nd->right);
     }
}
void pre_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        printf("%d--->",nd->val);   
        pre_order(nd->left);
        pre_order(nd->right);            
     }
}
void post_order(NODEPTR nd)
{
   if(nd!=NULL)
    {    
        post_order(nd->left);
        post_order(nd->right);
        printf("%d--->",nd->val);
     }
}
13. Write a function to insert a node into a binary search tree using recursion
struct node
{
   int val; 
   struct node *left,*right;
};
typedef struct node *NODEPTR;
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode; 
    if(newnode->val > nd->val)/*branch to right*/
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)/*branch to left*/
        nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
int main()
{
    NODEPTR root = NULL;
    root = insert_node(root,create_node(10));
    root = insert_node(root,create_node(22));
    root = insert_node(root,create_node(3));
   ....
}
   14. Explain the following terms 1) Strictly binary tree 2) Complete binary tree 3) Balanced binary tree
15. Given a list of numbers, write a program to create a binary search tree, avoiding duplicate numbers.
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
}
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)/*branch to right*/
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)/*branch to left*/
        nd->left = insert_node(nd->left,newnode); 
    else
   {
	printf("Duplicate nodes are not allowed");
    }
    return nd;   
}
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        in_order(nd->left);
        printf("%d---",nd->val);
        in_order(nd->right);
     }
} 
int main()
{
       NODEPTR root=NULL,delnode; 
       int n;
       do
       {
           NODEPTR newnode;
           printf("Enter value of node(-1 to exit):");
           scanf("%d",&n);
           if(n!=-1)
            {  
               newnode = create_node(n);
               root = insert_node(root,newnode);
             }
       } while (n!=-1);       
       printf("\nInorder traversal\n");
       in_order(root);         
       return 0;
}16. What is a binary tree? Explain the following terms 1) root node 2) leaf node 3) ancestor 4) descedents 5) siblings
17. What is a heap? What are the different types of heap?
18. What are the different types of rotations in an AVL tree.
19. What is an AVL tree? Write a program to insert a node to an AVL tree.
#include<stdio.h>
#include<stdlib.h>
struct avlNode
{
   int num;
   struct avlNode *left;
   struct avlNode *right;
};
typedef struct avlNode *NDPTR;
int height(NDPTR temp)
{
    if(temp!=NULL)
    {
       int h1 = height(temp->left);
       int h2 = height(temp->right);
       return ( h1>h2?h1:h2)+1;
    }
    return 0;
}
int balance_factor(NDPTR temp)
{
     int h1 = height(temp->left);
     int h2 = height(temp->right);
     return h1-h2;
}
NDPTR rr_rotation(NDPTR parent)
{
     NDPTR temp = parent->right;
     parent->right = temp->left;
     temp->left = parent;
     return temp;
}
NDPTR ll_rotation(NDPTR parent)
{
     NDPTR temp = parent->left;
     parent->left = temp->right;
     temp->right = parent;
     return temp;
}
NDPTR lr_rotation(NDPTR parent)
{
    NDPTR temp = parent->left;
    parent->left = rr_rotation(temp);
    return ll_rotation(parent);
}
NDPTR rl_rotation(NDPTR parent)
{
    NDPTR temp = parent->right;
    parent->right = ll_rotation(temp);
    return rr_rotation(parent);
}
NDPTR balance(NDPTR temp)
{
    int bal_factor = balance_factor(temp); 
    if (bal_factor>1)
    {
       
       if(balance_factor(temp->left)>0)
          temp = ll_rotation(temp);
       else
          temp = lr_rotation(temp);
    }
    else if (bal_factor<-1)
    {
       if(balance_factor(temp->right)>0)
          temp = rl_rotation(temp);
       else
          temp = rr_rotation(temp);
    }
    return temp;
}
NDPTR create_node(int num)
{
  NDPTR temp = (NDPTR)malloc(sizeof(struct avlNode));
  temp->left = temp->right = NULL;
  temp ->num = num;
  return temp;
}
NDPTR insert(NDPTR root,int value)
{
     if(root==NULL)
     {
        root = create_node(value); 
     }
     else if(value>root->num)
     {
        root->right = insert(root->right,value);
        root = balance(root);
     }
     else if(value<root->num)
    {
        root->left = insert(root->left,value);
        root = balance(root);
     }
     return root;
}
void pre_order(NDPTR root)
{
    if(root!=NULL)
    {
       printf("\n%d ",root->num);
       pre_order(root->left);
       
       pre_order(root->right);
    }
}
int main()
{
   NDPTR root = NULL;
   while(1)
   {
      int n;
      printf("Enter a node to insert :");
      scanf("%d",&n);
      if(n==-1)
         break;
      root = insert(root,n);
   }
   pre_order(root);
}
   20. What is a max heap? Write a function to add a value to a max heap.
 #include <stdio.h> 
void printArray(int *arr,int n);
void swap(int *a,int *b)
{
    int temp = *a;
   *a = *b;
   *b = temp;
}
  
void heapfilterup( int arr[],int k )
   {
      /*move newly added value up to maintain heap*/
      int parent=k/2;
      while ( parent > 0 )      
      {
       parent = k/2;   
      if ( arr[k]>arr[parent] )
      {    
         swap(&arr[parent],&arr[k]);
         k = parent;
      }
      else
      {
        break;    
      }
      }
   }
void insert(int arr[], int n, int newvalue)
{
     arr[n-1] = newvalue; 
     heapfilterup(arr,n-1);   
}
void readArray(int arr[], int n)
{
    int i;
    printf("Enter elements of the max heap in order:");
    for ( i=1; i<n; ++i)
    {
     printf("a[%d]",i);
     scanf("%d",&arr[i]);
   } 
} 
void printArray(int arr[], int n)
{
    int i;
    for ( i=1; i<n; ++i)
     printf("%d ",arr[i]);
   printf( "\n");
}
// Driver program
int main()
{
    int arr[40];int n,val; 
    printf("What is heap size");
    scanf("%d",&n);
    n++;
    readArray(arr,n);
   //we dont store a value at arr[0]
    printf("Enter new value to be inserted:");
    scanf("%d",&val);
    n++;
    insert(arr,n,val); 
    printf("Now the heap is \n");
    printArray(arr, n);
}21. With the help of examples explain 1) Level of a binary tree 2) Depth of a binary tree
22. Write a program to covert a binary tree into sorted doubly linke list. Do not create any nodes but just modify links.
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
void convert_to_dll(NODEPTR nd,NODEPTR*headptr)
{
   static NODEPTR prevnode;
   if(nd!=NULL)
    {       
        convert_to_dll(nd->left,headptr);
        if(prevnode!=NULL){
           prevnode->right = nd;
           nd->left = prevnode;
        }
        else{
           *headptr = nd;
        }
        prevnode = nd; 
        convert_to_dll(nd->right,headptr);
     }
}
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
        nd->left = insert_node(nd->left,newnode); 
    return nd;   
} 
void print_dll(NODEPTR nd)
{
   NODEPTR temp = nd;
    while(nd)
      {
        printf("%d---->",nd->val);
        nd = nd->right;
       } 
} 
void inorder(NODEPTR nd)
{
   if(nd!=NULL)
   {	
      inorder(nd->left);
      printf("%d ",nd->val);
      inorder(nd->right);
    }
}
int main()
{
       NODEPTR root=NULL,delnode,head;  
       int n;
       do
       {
           NODEPTR newnode;
           printf("Enter value of node(-1 to exit):");
           scanf("%d",&n);
           if(n!=-1)
            {  
               newnode = create_node(n);
               root = insert_node(root,newnode);
             }
       } while (n!=-1);
        
       head = NULL;
       convert_to_dll(root ,&head);
       print_dll(head); 
       return 0;
}23. Given a binary tree, write a function to determine whether it is a binary search tree
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
static int prevValue;
int isBST(NODEPTR nd)
{ 
 if(nd!=NULL)
  {
     if(!isBST(nd->left))
       return 0;
     if(nd->val<prevValue)
       return 0;
     prevValue = nd->val;
     return isBST(nd->right);
  }
  else
    return 1;
}
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
}
 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
        nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
NODEPTR create_tree1()
{
        NODEPTR n1,n2,n3,n4,n5,n6,n7,root;
        n1 = create_node(10);
        n2 = create_node(20);
        n3 = create_node(30);
        n4 = create_node(40);
        n5 = create_node(50);
        n6 = create_node(60);
        n7 = create_node(70);
        root = n3;
        n3->left = n1;
        n1->right = n2;
        n3->right = n6;
        n6->left = n4;
        n4->right = n5;
        n6->right = n7;
        return root;
}
NODEPTR create_tree2()
{
        NODEPTR n1,n2,n3,n4,n5,n6,n7,root;
        n1 = create_node(10);
        n2 = create_node(20);
        n3 = create_node(30);
        n4 = create_node(40);
        n5 = create_node(50);
        n6 = create_node(60);
        n7 = create_node(70);
        root = n3;
        n3->left = n1;
        n1->left = n2;
        n3->right = n6;
        n6->left = n4;
        n4->right = n5;
        n6->right = n7;
        return root;
}
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        in_order(nd->left);
        printf("%d---",nd->val);
        in_order(nd->right);
     }
} 
int main()
{
       NODEPTR root=NULL,delnode; 
       int n;
       root = create_tree1();
       printf("\nInorder traversal\n");
       in_order(root);
       if(isBST(root))
          printf("The tree is a binary search tree");
       else
          printf("The tree is not a binary search tree");
       root =create_tree2();
      in_order(root);
       if(isBST(root))
          printf("this tree is a binary search tree");
       else
          printf("this tree is not a binary search tree");            
       return 0;
}24. Determine whether an input array is a post-order traversal sequence of a binary tree or not. Assume all numbers in an input array are unique.
int is_array_post_order(NODEPTR nd,int *arr)
{
   static int index=0; 
   if(nd!=NULL)
    {
        int leftst,rightst;	
        leftst =  is_array_post_order(nd->left,arr);       
        rightst =  is_array_post_order(nd->right,arr); 
        if(arr[index++]!=nd->val)
            return 0; 
        if( leftst==0 || rightst==0)
       { 
		return 0;
       }
        else  return 1;
     }
     return 1;
}25. Given a binary search tree and a value k, find a node in the binary search tree whose value is closest to k.
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
        nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        in_order(nd->left);
        printf("%d---",nd->val);
        in_order(nd->right);
     }
}
int absolute(int m)
{
   return m<0?-m:m;
}
int find_closest_num(NODEPTR nd,int num)
{
      int mindiff=absolute(nd->val - num);
      int closest_val=nd->val;
      while(nd!=NULL)
      {
          int d = absolute(num - nd->val);
          if( d<mindiff)
         {
              mindiff = d;
              closest_val = nd->val;
          } 
          if(num>nd->val)
              nd = nd->right;
          else if(num<nd->val)
              nd = nd->left;
          else	
              return nd->val;/*diff is 0*/
     }
     return closest_val;
}
int main()
{
       NODEPTR root=NULL,delnode; 
       int n;
       do
       {
           NODEPTR newnode;
           printf("Enter value of node(-1 to exit):");
           scanf("%d",&n);
           if(n!=-1)
            {  
               newnode = create_node(n);
               root = insert_node(root,newnode);
             }
       } while (n!=-1);
       
       printf("\nInorder traversal\n");
       in_order(root);
      
       while(1)
       {
          NODEPTR snode;
          int num1,num2;
          printf("Enter a number(-1 to stop):");
          scanf("%d",&num1);
          if(num1==-1)
             break;
          int a =find_closest_num(root,num1);          
          printf("closest value to %d is %d\n",num1,a);
       }
       return 0;
}26. Write a function for breadth first traversal of a binary tree.
 #include<stdio.h>
#include<stdlib.h>
struct btnode
{ 
    int value; 
    struct btnode *left, *right; 
};
typedef struct btnode *NODEPTR ;
#define MAX 40
struct queue
{ 
   NODEPTR nodes[40];
   int rear,front;
}; 
 NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->value > nd->value)
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->value <  nd->value)
        nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
 
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct btnode));
     temp->value = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
void enqueue(struct queue *qptr,NODEPTR newnode)
{
    if(qptr->rear>=MAX)
      {
        printf("Queue overflow");
        return;
      }
    qptr->rear++;
    qptr->nodes[qptr->rear]=newnode;
}
int is_empty(struct queue qptr)
{
    if (qptr.front>qptr.rear)
      return 1;
    return 0;
}
  
NODEPTR dequeue(struct queue *qptr)
{
    if(is_empty(*qptr))
    {
        printf("Queue empty");
        return NULL;
    }    
    NODEPTR temp= qptr->nodes[qptr->front];
    qptr->front++;
    return temp;
}  
/* displaying elements using BFS traversal */
void bfs_traverse(NODEPTR root)
{
    struct queue q1;
    NODEPTR nd;
    q1.front=0;q1.rear =-1;
    enqueue(&q1,root);
    while(!is_empty(q1))
    {
        nd = dequeue(&q1) ;
        if(nd==NULL)
          break;
        printf("%d  ",nd->value);    	
        if (nd->left != NULL)
            enqueue(&q1,nd->left);
        if (nd->right != NULL )
            enqueue(&q1,nd->right);         
    }     
}
int main() 
{ 
    NODEPTR root = NULL,newnode ; 
    int num = 1; 
    printf("Enter the elements of the tree(enter -1 to exit)\n"); 
    while (1) 
    {     
        scanf("%d",  &num); 
        if (num  ==  -1) 
            break; 
        newnode = create_node(num);
        root = insert_node(root,newnode);
    }
    printf("elements in bfs are\n"); 
    bfs_traverse(root);
    
}27. Write a function for depth first traversal of a binary tree
28. Write a program to print kth smallest element of a binary search tree
int kth_smallest(NODEPTR nd,int k )
{
   static int m=0;  
   if(nd!=NULL)
    {
        int a =  kth_smallest(nd->left,k );
        m++;
        if(m==k)
           return nd->val;
        int b= kth_smallest(nd->right,k);
        return a;
     }
}
 
int main()
{
       NODEPTR root=NULL,delnode; 
       int n;
       do
       {
           NODEPTR newnode;
           printf("Enter value of node(-1 to exit):");
           scanf("%d",&n);
           if(n!=-1)
            {  
               newnode = create_node(n);
               root = insert_node(root,newnode);
             }
       } while (n!=-1);
       
       printf("\nInorder traversal\n");
       in_order(root);
      
       printf("Enter k:");
       scanf("%d",&n);
       int smallest=
       kth_smallest(root,n);
       printf("%dth smallest element is %d\n",n,smallest);
       return 0;
}
/*compile this with binary tree library*/29. Write a program to merge two binary search trees
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
    return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
     nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
     nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
void convert_to_dll(NODEPTR nd,NODEPTR*headptr)
{
   static NODEPTR prevnode;
   if(nd!=NULL)
    {    
    convert_to_dll(nd->left,headptr);
     if(prevnode!=NULL){
        prevnode->right = nd;
        nd->left = prevnode;
     }
     else{
        *headptr = nd;
     }
     prevnode = nd; 
     convert_to_dll(nd->right,headptr);
     }
}
 
NODEPTR merge_bsts(NODEPTR root,NODEPTR root2)
{
     NODEPTR head = NULL;
     convert_to_dll(root2,&head);
     while(head!=NULL)
     {
	NODEPTR temp = head;
	head = head->right;
                 temp->left = temp->right = NULL;/*detach from list*/
	root = insert_node(root,temp);/*insert into first tree*/
      }
      return root;
}
void inorder(NODEPTR nd)
{
   if(nd!=NULL)
   {	
	inorder(nd->left);
	printf("%d ",nd->val);
                inorder(nd->right);
    }
}
int main()
{
    NODEPTR root=NULL,delnode,head; 
    NODEPTR root2 = NULL;
    int n;
    do
    {
        NODEPTR newnode;
        printf("Enter value of node(-1 to exit):");
        scanf("%d",&n);
        if(n!=-1)
         {  
         newnode = create_node(n);
         root = insert_node(root,newnode);
          }
    } while (n!=-1);
    printf("Second bst:");
    do
    {
        NODEPTR newnode;
        printf("Enter value of node(-1 to exit):");
        scanf("%d",&n);
        if(n!=-1)
         {  
         newnode = create_node(n);
         root2 = insert_node(root2,newnode);
          }
    } while (n!=-1);
    head = NULL; 
    root  = merge_bsts(root,root2); 
    printf("Merged bst is ");
    inorder(root);
    return 0;
}30. Find the sum of all elements in level k of a binary search tree
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
int sum_at_levelk(NODEPTR nd,int level,int k)
{   
   if(nd==NULL)
      return 0;
   if(level<k) 
      {
       int a = sum_at_levelk(nd->left,level+1,k);
       int b = sum_at_levelk(nd->right,level+1,k);
      return a+b;
    } 
   if(level==k)
   { 
      return nd->val;
   }
}
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
       nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
       nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
     in_order(nd->left);
     printf("%d---",nd->val);
     in_order(nd->right);
     }
}
   
int main()
{
    NODEPTR root=NULL,delnode; 
    int n,k;
    do
    {
        NODEPTR newnode;
        printf("Enter value of node(-1 to exit):");
        scanf("%d",&n);
        if(n!=-1)
         {  
         newnode = create_node(n);
         root = insert_node(root,newnode);
          }
    } while (n!=-1);
    
    printf("\nInorder traversal\n");
    in_order(root);
    while(1)
    {
       printf("Enter level (-1 to exit):");
        scanf("%d",&k);
       if(k==-1)
          break;
        printf("Sum of elements at level %d is %d \n",k,sum_at_levelk(root,0,k));
    } 
    return 0;
}31. Write a function to find the lowest common ancestor of two given nodes in a binary search tree
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
NODEPTR lowest_common_ancestor(NODEPTR root, int num1,int num2)
{
   NODEPTR temp = root;
   while(temp!=NULL)
   {
        if(num1>temp->val && num2>temp->val ) 
              temp = temp->right; 
        else if(num1<temp->val && num2<temp->val)
              temp= temp->left;
        else
              break; 
    }
    return temp;  
} 
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
       return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
        nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
        nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
        in_order(nd->left);
        printf("%d---",nd->val);
        in_order(nd->right);
     }
} 
int main()
{
       NODEPTR root=NULL,delnode; 
       int n;
       do
       {
           NODEPTR newnode;
           printf("Enter value of node(-1 to exit):");
           scanf("%d",&n);
           if(n!=-1)
            {  
               newnode = create_node(n);
               root = insert_node(root,newnode);
             }
       } while (n!=-1);
       
       printf("\nInorder traversal\n");
       in_order(root);
      
       while(1)
       {
          NODEPTR snode;
          int num1,num2;
          printf("Enter two values num1 and num2:");
          scanf("%d %d",&num1,&num2);
          snode = lowest_common_ancestor(root,num1,num2);
          if(snode==NULL)
             printf("Value not found");
          else 
             printf("ancestor is %d\n",snode->val);
       }
       return 0;
}32. Write a function to convert a binary tree into its mirror that is for each node, its left subtree and right subtree must be swapped.
void mirror_tree(NODEPTR root)
{
   if(root!=NULL)
   {
         NODEPTR temp = root->left;
         root->left = root->right;
         root->right = temp;
         mirror_tree(root->left);
         mirror_tree(root->right);
    }
}
33. Given two binary trees, write a compare function to check if they are equal or not. Being equal means that they have the same value and same structure.
#include<stdio.h>
#include<stdlib.h>
struct node
{
   int val;
   struct node *left;
   struct node *right;
};
typedef struct node *NODEPTR;
NODEPTR create_node(int num)
{
     NODEPTR temp = (NODEPTR)malloc(sizeof(struct node));
     temp->val = num;
     temp->left = NULL;
     temp->right = NULL;
     return temp;
} 
NODEPTR insert_node(NODEPTR nd,NODEPTR newnode)
{
    if(nd==NULL)
    return newnode;/* newnode becomes root of tree*/
    if(newnode->val > nd->val)
     nd->right = insert_node(nd->right,newnode);
    else if(newnode->val <  nd->val)
     nd->left = insert_node(nd->left,newnode); 
    return nd;   
}
void in_order(NODEPTR nd)
{
   if(nd!=NULL)
    {
     in_order(nd->left);
     printf("%d---",nd->val);
     in_order(nd->right);
     }
}
int equal_trees(NODEPTR nd1,NODEPTR nd2)
{
    if(nd1==nd2)
    return 1;/*both are null*/
    if(nd1==NULL || nd2==NULL )     
      return 0;/*either but not both*/
    if(nd1->val!=nd2->val)
      return 0;
      else
    {
      int l= equal_trees(nd1->left,nd2->left);
      int r = equal_trees(nd1->right,nd2->right);
      return l&r;
    }
}    
      
NODEPTR create_tree()
{
    NODEPTR root = NULL;
    int n;
    do
    {
        NODEPTR newnode;
        printf("Enter value of node(-1 to exit):");
        scanf("%d",&n);
        if(n!=-1)
         {  
      newnode = create_node(n);
         root = insert_node(root,newnode);
          }
    } while (n!=-1);
     return root;
}
 
int main()
{
    NODEPTR root=NULL,delnode; 
    int n;
    NODEPTR root1,root2;
    printf("First tree:");
    root1 = create_tree();
    in_order(root1);
    printf("Second tree:");
    root2 = create_tree();
    in_order(root2);
    if(equal_trees(root1,root2))
       printf("The two tree are equal");
    else
       printf("The two trees are not equal"); 
    
}34. Write a function to display the numbers in order of a binary search tree in the range x to y. Hint on the analysis: the visited nodes are found to the right of one path in the tree and to the left of another.
void in_order_middle(NODEPTR nd,int x, int y)
{
    if(nd  )
    { 
        if(nd->val >=x)
             in_order_middle(nd->left,x,y);
        if(nd->val>=x && nd->val<=y)
	    printf("%d  ",nd->val);
        if(nd->val <=y)
           in_order_middle(nd->right,x,y); 
    }
}