1. Show how a stack can be used to evaluate a postfix expression with the help of this example. 632-5*+1^7+
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define ERRCODE 12345
#define DIVBYZERO 23456
struct node
{
    double n1;
    struct node *next;
};
typedef struct node *NODEPTR;
NODEPTR createnode(double num)
{
    NODEPTR newnode = (NODEPTR) malloc(sizeof(struct node));
    newnode->n1 = num;
    newnode->next = NULL;
}
NODEPTR  push(double num,NODEPTR top)
{
   NODEPTR newnode = createnode(num);
   newnode->next = top;
   top = newnode;
   return top;
}
double pop(NODEPTR * top)
{
   if(top==NULL)
	return ERRCODE;
   NODEPTR temp = *top;
   *top =(*top)->next;
   double val = temp->n1;
   free(temp);
   return val;
}
int is_operator(char ch)
{
    switch(ch)
    {
	case '+':
	case '-':
	case '/':
	case '*':
	case '^':
		return 1;
        default : return 0;
    }
}
 
double evaluate(char *postfix)
{
     char ch;
     double ans,n1,n2;
     NODEPTR top = NULL;
     while(ch =*postfix++)
     {
        if(isdigit(ch))
        {
          double n = ch-48;
          top = push(n,top);
        }
        else if(is_operator(ch))
       {
           n1 = pop(&top);
           if(n1==ERRCODE)
              return ERRCODE;
           n2 = pop(&top);
           if(n2 ==ERRCODE)
              return ERRCODE;
          switch(ch)
          {
            case '+': ans = n1+n2; 
                    break;
            case '-': ans = n2 - n1;
  	  break;
            case '*': ans = n1*n2;
                 break;
           case '/': if(n1!=0)
                   ans = n2/n1;
                else
                   return DIVBYZERO;	 
                break;
          case '^':ans = pow(n2,n1);
	  break;
          }
          top = push(ans,top);
      }
    }
    ans = pop(&top);
    return ans;
}
    
   
int main()
{
   char postfix[30];
   double ans;
   printf("Enter postfix expression (leave space between values):");
   fgets(postfix,29,stdin);
   ans = evaluate(postfix);
   printf("The value of expression is %f",ans);
   return 0;
}2. Convert the following expressions into prefix and postfix. A+B*C-D/E*H (A+B^C^D)*(E+F/D)
3. What is stack data structure? Write push, pop, isEmpty and isFull functions for a stack using array implementation
#include<stdio.h>
#define MAX 30
struct stack
{
    int arr[MAX];
    int top;
};
void push(struct stack *s, int val)
{
   if( is_full(s))
      printf("Stack overflow");
   else
   {
      (s->top)++;
      s->arr[s->top]=val;
   }
    
}
int is_empty(struct stack *s)
{
    return s->top==-1;
}
int is_full(struct stack *s)
{
    return s->top>=MAX;
}
int pop(struct stack *s)
{
    int val = -1;
    if(is_empty(s))
      printf("Stack empty");
    else
     {
        int t = s->arr[s->top];
        s->top--;
        val = t;
      }
    return val;
}
    
int main()
{
    struct stack s1;
    s1.top = -1;
    int option;
    while(1)
    {
       printf("Enter 1- push 2-pop 3 - exit:");
       scanf("%d",&option);
       if(option==3)
          break;
       else if(option==1)
      {
          int num;
          printf("Enter value to push:");
          scanf("%d",&num);
          push(&s1,num);
        }
        else if(option==2)
       {
           int num;
           num = pop(&s1);
           if(num!=-1)
              printf("value popped is %d\n",num); 
        }   
    }
    return 0;
}
    
    4. Write an algorithm to convert an infix expression into postfix. And also write code for this.
#include<stdio.h>
#include"stack.h"
int is_operator(char ch)
{
   switch(ch)
   {
      case '+':
      case '-':
      case '/':
      case '*':
      case '%':
      case '^':
                return 1;
      default : return 0;
   }
}
int priority(char ch)
{
 switch(ch)
   {
      case '+':
      case '-':return 1;
      case '/':
      case '*':
      case '%':return 2;
      case '^':return 3;
                 
      default : return 0;
   }
}
void convert(char *input, char *output)
{
   struct stack s1;
   s1.top = -1;
   while(*input)
   {
   char ch = *input++;
   char ch2;
   if(ch=='(')
      push(&s1,ch);
   else if(ch==')')
   {
       while(!is_empty(&s1)  && ( (ch=pop(&s1))!='('))
          *output++ = ch;
    }
    else 
    if(is_operator(ch))
    {
       while(!is_empty(&s1)  &&  priority(peek(&s1))>=priority(ch))
          *output++ = pop(&s1);
       push(&s1,ch);
     }
     else
       *output++ = ch;
    }
    while(!is_empty(&s1))
       *output++ = pop(&s1);
    *output = 0;
}               
int main()
{
   char infix[40],postfix[40];
   printf("Enter infix expression:");
   scanf("%s",infix);
   convert(infix,postfix);
   printf("the postfix expression is %s\n",postfix);
   return 0;
}
/*stack implementation not shown */5. Explain how a stack can be implemented using a linked list. Write C functions for push, pop, isempty for this method.
#include<stdio.h>  
#include<stdlib.h>
#define ERROR -1000
 struct node  
 {  
   int n;  
   struct node *next;   
 };  
 typedef struct node * NODEPTR;  
 
 NODEPTR create_node(int value)  
 {  
   NODEPTR temp = (NODEPTR) malloc(sizeof(struct node));  
   temp->next = NULL;  
   temp->n = value;  
   return temp;  
 } 
 NODEPTR push(NODEPTR top,int n)
 { 
     NODEPTR newnode = create_node(n);
     newnode->next = top;
     top = newnode;
     return top;
}
int isempty(NODEPTR top)
{
   return top==NULL;
}
int pop(NODEPTR *topPtr)
{
   if(isempty(*topPtr))
    return ERROR;
   int num = (*topPtr)->n;
   NODEPTR temp = *topPtr;
   *topPtr = (*topPtr)->next;
   free(temp);
   return num;
}
 int main()  
 {  
     NODEPTR top = NULL;
     NODEPTR nd; 
     while(1)
     {  
       int option,value; 
       printf("Enter 1- push 2- pop 3 - exit"); 
       scanf("%d",&option);
       if(option==3)
          break;
       switch(option)
       {
          case 1:  printf("new value to push=");  
            scanf("%d",&value);   
            top = push(top,value);
            break;
         case 2:  value = pop(&top);
           if(value==ERROR)
             printf("Stack empty\n");
           else
             printf("Value popped is %d\n",value);
        break; 
     }  
    }     
 }  
6. Design a method to create two stacks in a single array so that either stack overflows until the memory is completely filled and a stack is never moved to another memory location. Write push1, push2, pop1, pop2, display1 and display2 functions for this in C.
#include<stdio.h>
#define MAX 5
struct two_stacks
{
    int arr[MAX];
    int top1,top2;
};
void push1(struct two_stacks *s, int val)
{
   if( is_full(s))
      printf("Stack overflow");
   else
   {
      (s->top1)++;
      s->arr[s->top1]=val;
   }    
}
void push2(struct two_stacks *s, int val)
{
   if( is_full(s))
      printf("Stack overflow");
   else
   {
      (s->top2)--;
      s->arr[s->top2]=val;
   }    
}
int is_empty1(struct two_stacks *s)
{
    return s->top1==-1;
}
 
int pop1(struct two_stacks *s)
{
    int val = -1;
    if(is_empty1(s))
      printf("Stack empty");
    else
     {
        int t = s->arr[s->top1];
        s->top1--;
        val = t;
      }
    return val;
}
  
int pop2(struct two_stacks *s)
{
    int val = -1;
    if(is_empty2(s))
      printf("Stack empty");
    else
     {
        int t = s->arr[s->top2];
        s->top2++;
        val = t;
      }
    return val;
}  
int is_empty2(struct two_stacks *s)
{
    return s->top2==MAX;
}
int is_full(struct two_stacks *s)
{
    return (s->top2-s->top1==1)?1:0;    
}
int main()
{
    struct two_stacks s;
    s.top1 = -1;
    s.top2 = MAX;    
    int option;
    while(1)
    {
      printf("Enter 1- push to s1, 2-pop from s1, 3- push to s2, 4-pop from s2,  5 - exit:");
      scanf("%d",&option);
        
      if(option==5)
          break;
      else if(option==1||option==3)
     {
         int num;
         printf("Enter value to push:");
         scanf("%d",&num);
        if(option==1) 
           push1(&s,num);
        else
           push2(&s,num);
       }
      else if(option==2||option==4)
     {
         int num;
         if(option==2)
           num = pop1(&s);
         else
           num = pop2(&s);
           if(num!=-1)
              printf("value popped is %d\n",num);	
        }             
    }
    return 0;
}
    
    7. Write a function to convert a given postfix expression to infix expression.
#include<stdio.h>
#include<string.h>
#include<stdlib.h> 
struct node
{
    char str[30];
    struct node *next;
};
struct node *createnode(char *str)
{
    struct node *newnode = (struct node*) malloc(sizeof(struct node));
    strcpy(newnode->str,str);
    newnode->next = NULL;
}
struct node * push(char *str,struct node *top)
{
   struct node *newnode = createnode(str);
   newnode->next = top;
    top = newnode;
   return top;
}
char * pop(struct node ** top)
{
   static char str[30];
   if(*top==NULL)
    return NULL;
   struct node * temp = *top;
   *top =(*top)->next;
   strcpy(str,temp->str);
   
   free(temp);
   return str;
}
int is_operator(char ch)
{
    switch(ch)
    {
    case '+':
    case '-':
    case '/':
    case '*':
    case '^':
    return 1;
        default : return 0;
    }
}
 
char *concat(char *s1,char *s2,char ch)
{
   char *result = (char*)malloc(60);
   int i=1;
   result[0] = '(';
   while(*s1)
     result[i++]=*s1++;
   result[i++]=ch;
   while(*s2)
     result[i++]=*s2++;
   result[i++]=')';/*enclose in parantheses*/
   result[i]=0;
   return result;
}
int convert(char *postfix,char *infix)
{
     char ch;
     char oper1,oper2,opernew;
     char *expr1=(char*)malloc(30);
     char *expr2=(char*)malloc(30);
     char *expr3 = (char*)malloc(60);
     struct node *top = NULL;
     int iserr = 0;
     while(ch =*postfix++)
     {
      if(isdigit(ch) ||isalpha(ch))
      {
         char  str[] = {ch,0};
         top = push(str,top);
      }
      else if(is_operator(ch))
     {
        char* str = pop(&top);
        if(str==NULL)
        {
           printf("pop error");
           iserr=1;
           break;
        }        
        strcpy(expr1, str);         
        str = pop(&top);        
        if(str==NULL)
        {
         iserr = 1;
         printf("Error");
         break;
        }
        strcpy(expr2,str);
       strcpy(expr3, concat(expr2,expr1,ch));    
       top = push(expr3,top);
      }
    } 
    if(!iserr)
        strcpy(infix,pop(&top));
    else
        return 0;
}
    
   
int main()
{
   char postfix[30];char infix[30];
   double ans;
   printf("Enter postfix expression :");
   scanf("%s",postfix); 
   if(convert(postfix,infix))
   printf("The expression in infix is %s",infix);
   return 0;
}8. Write a function to check if a given expression is having balanced brackets.
#include<stdio.h>
#include<string.h>
#include<stdlib.h> 
#define ERRORCHAR 65
struct node
{
    char ch;
    struct node *next;
};
struct node *createnode(char ch)
{
    struct node *newnode = (struct node*) malloc(sizeof(struct node));
    newnode->ch = ch;
    newnode->next = NULL;
    return newnode;
}
int is_empty(struct node *top)
{
    return top==NULL;
}
struct node * push(char ch,struct node *top)
{
   struct node *newnode = createnode(ch);
   newnode->next = top;
   top = newnode;
   return top;
}
char pop(struct node ** top)
{
   char ch;
   if(*top==NULL)
	return ERRORCHAR;
   struct node * temp = *top;
   *top =(*top)->next;
   ch = temp->ch;
   
   free(temp);
   return ch;
}
int is_opening_bracket(char ch)
{
    switch(ch)
    {
        case '(':
        case '[':
        case '{':
	   return 1;
        default : return 0;
    }
}
int is_closing_bracket(char ch)
{
    switch(ch)
    {
        case ')':
        case ']':
        case '}': 
	    return 1;
        default : return 0;
    }
} 
 
int is_matching_bracket(struct node **top,char ch)
{
    char ch2 = pop(top);
    if(ch2!=ERRORCHAR)
    {
        if(ch2=='(' && ch==')' )
           return 1;
        if(ch2=='[' && ch==']' )
           return 1;
       if(ch2=='{' && ch=='}' )
           return 1;
     }
     return 0; 
} 
int is_balanced(char *expression)
{
     char ch;
      
     struct node *top = NULL;
     while(ch =*expression++)
     {
        if(is_opening_bracket(ch))
        {
            top = push(ch,top);
        }
        else if(is_closing_bracket(ch))
        {
            if(!is_matching_bracket(&top,ch))
            {
               return 0;           
             }
        }
     }
     return is_empty(top);
}    
   
int main()
{
   char expression[50]; 
   printf("Enter an expression :");
   scanf("%s",expression); 
   if(is_balanced(expression))
   {
        printf("The expression has balanced brackets");
   }
   else
   {
        printf("The expression has unbalanced brackets");
   }
   return 0;
}9. Given two integer sequences, one of which is the push sequence of a stack, please check whether the other sequence is a corresponding pop sequence or not.
#include<stdio.h>
void read_array(int *arr,int n)
{
   int i;
   printf("Enter the elements of the array:");
   for (i=0;i<n;i++)
     scanf("%d",&arr[i]);
}
void write_array(int *arr,int n)
{
   int i;
   printf("The array is ");
   for (i=0;i<n;i++)
     printf("%d  ",arr[i]);
}
int is_pop_sequence(int *arr1,int *arr2,int n)
{
    int i,j;
    for(i=0,j=n-1;i<n;i++,j--)
      if(arr1[i]!=arr2[j])
         return 0;
    return 1;
}
int main()
{
    int arr1[20], arr2[20];
    int n;
    printf("Enter the length of sequence:");
    scanf("%d",&n);
    read_array(arr1,n);
    read_array(arr2,n);
    if(is_pop_sequence(arr1,arr2,n))
       printf("These two correspond to push and pop sequences");
    else
       printf("These are not push and pop sequences of same stack");
}10. Write a recursive function to reverse a stack .
 #include<stdio.h>  
#include<stdlib.h>
#define ERROR -1000
 struct node  
 {  
   int n;  
   struct node *next;   
 };  
 typedef struct node * NODEPTR;  
 
 NODEPTR create_node(int value)  
 {  
   NODEPTR temp = (NODEPTR) malloc(sizeof(struct node));  
    temp->next = NULL;  
   temp->n = value;  
   return temp;  
 } 
 void push(NODEPTR* topptr,int n)
 { 
     NODEPTR newnode = create_node(n);
     newnode->next = *topptr;
     *topptr = newnode; 
}
int isempty(NODEPTR top)
{
   return top==NULL;
}
int pop(NODEPTR *topPtr)
{
   if(isempty(*topPtr))
       return ERROR;
   int num = (*topPtr)->n;
   NODEPTR temp = *topPtr;
   *topPtr = (*topPtr)->next;
   free(temp);
   return num;
}
void bottom_insert(NODEPTR *topptr,int n)
{
  if(isempty(*topptr))
     push(topptr,n);
  else
    {
    int a = pop(topptr);
    bottom_insert(topptr,n);
    push(topptr,a);
    }
}
void reverse(NODEPTR *topptr)
{
  if(*topptr!=NULL)
  {
    int n= pop(topptr);
    reverse(topptr);
    bottom_insert(topptr,n);
  }
}
 int main()  
 {  
     NODEPTR top = NULL;
     NODEPTR nd;
     while(1)
     {  
       int option,value; 
       printf("Enter 1- push 2- pop 3 - reverse stack 4 - exit"); 
       scanf("%d",&option);
       if(option==4)
          break; 
       switch(option)
       {
           case 1:  printf("new value to push=");  
              scanf("%d",&value);  
              push(&top,value);
              break;
           case 2:  value = pop(&top);
             if(value==ERROR)
                 printf("Stack empty\n");
             else
                 printf("Value popped is %d\n",value);
             break; 
          case 3:  reverse(&top);
             break;
        }  
    }     
 }  
11. Write a function to print next greater element for all elements in an array. If there is no NGE , it must print -1 for that element
#include<stdio.h>
#include"stackint.h"
void read_array(int *arr,int sz)
{
     int i;
     for(i  =0;i<sz;i++)
     {
       printf("arr[%d]=",i);
       scanf("%d",&arr[i]);
     }
}
void print_array(int *arr,int sz)
{
     int i;
     for(i  =0;i<sz;i++)
     {
       printf("arr[%d]=",i);
       printf("%d   ",arr[i]);
     }
     printf("\n");
}
void next_greater_elements(int *arr,int n)
{
     STACK s1;
     int i;
     s1.top=-1;
     push(&s1,arr[0]); 
     for(i=1;i<n;i++)
     {
        while (!is_empty(&s1) && peek(&s1) < arr[i]) 
	{
                 printf("Next greater element for %d =%d\n" ,
	 	             + pop(&s1), arr[i]);
                }
 	push(&s1,arr[i]);  
     }
     while(!is_empty(&s1))
        printf("Next greater element for %d is -1\n",pop(&s1));
}
int main()
{
    int arr[50];
    int sz; 
    printf("Enter the size of array:"); 
    scanf("%d",&sz);
    read_array(arr,sz);
    print_array(arr,sz);
   
    next_greater_elements(arr,sz);
    return 0;
}12. Implement a stack with min() function which returns the minimum value of a stack. All of push(), pop() and min() function must have time complexity of O(1)
  #include<stdio.h>  
#include<stdlib.h>
#define ERROR -1000
 struct node  
 {  
   int value;  
   struct node *next;   
 };  
 typedef struct node * NODEPTR;  
 
 NODEPTR create_node(int value)  
 {  
   NODEPTR temp = (NODEPTR) malloc(sizeof(struct node));  
    temp->next = NULL;  
   temp->value= value;  
   return temp;  
 } 
 NODEPTR push(NODEPTR top,int val)
 { 
     NODEPTR newnode = create_node(val);
     newnode->next = top;
     top = newnode;
     return top;
}
int isempty(NODEPTR top)
{
   return top==NULL;
}
int pop(NODEPTR *topPtr)
{
   if(isempty(*topPtr))
       return ERROR;
   int num = (*topPtr)->value;
   NODEPTR temp = *topPtr;
   *topPtr = (*topPtr)->next;
   free(temp);
   return num;
}
int peek(NODEPTR nd)
{
   return nd->value;
}
void push1(NODEPTR*topptr,NODEPTR* mintopptr,int val)
{
     int minval =val;
     if(*mintopptr!=NULL)
        {
           int temp = peek(*mintopptr);
           if (temp<minval)
               minval = temp;
        }
     *topptr = push(*topptr,val);
     *mintopptr = push(*mintopptr,minval);
 }
 int pop1(NODEPTR* topptr,NODEPTR *mintopptr)
 {
   if(!isempty(*topptr))
   {
    pop(mintopptr);
    return pop(topptr);
   }else
       return ERROR;
 }
      
int findmin(NODEPTR mintop)
{
   if(mintop==NULL)
      return -1;
   return mintop->value;
}   
 
 int main()  
 {  
     NODEPTR top = NULL;
     NODEPTR nd;
     NODEPTR mintop=NULL;
     while(1)
     {  
       int option,value; 
       printf("Enter 1- push 2- pop 3 - exit 4- find minimum"); 
       scanf("%d",&option);
       if(option==3)
          break;
       switch(option)
       {
           case 1:  printf("new value to push=");  
       		    scanf("%d",&value);   
                    push1(&top,&mintop,value);
                    break;
           case 2:  value = pop1(&top,&mintop);
                    if(value==ERROR)
                         printf("Stack empty\n");
                    else
			 printf("Value popped is %d\n",value);
                    break; 
           case 4:  value=findmin(mintop);
                    if(value==-1)
                        printf("Stack empty\n");
                    else
                    printf("Minimum of stack is %d\n",value);
             
                    break;
        }  
    }     
 }  
13. Write a program to reverse a string using stack.
void reverseString(char *str)
{
    struct stack s;
    s.top = -1;
    char ch;
    char *temp = str;
    while(ch=*str++)/*till '\0'*/
    {
       push(&s,ch);
    }
    str = temp;/*go to beg address*/
    while(!is_empty(&s))
      *str++ = pop(&s);      
}
int main()
{
    char str[50];
    printf("Enter a string");
    fgets(str,49,stdin);
    reverseString(str);
    printf("The reversed string is %s\n",str);
    return 0;
}14. With the help of a stack, determine whether a given string is a palindrome.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 70
struct stack
{
    int arr[MAX];
    int top;
};
char pop(struct stack *s);
void push(struct stack *s, char val);
int is_palindrome(char *str)
{
     char *str2=str;
     struct stack s;
     s.top = -1;
     while(*str)
     {
        char ch = *str++;
        push(&s,ch);
     }
     while(*str2 && !is_empty(s))
     {
         char ch = pop(&s);
         if( *str2 !=ch)             
             return 0;
         str2++;
      }
      return 1;
}   
int is_full(struct stack *s)
{
    return s->top>=MAX;
}
void push(struct stack *s, char val)
{
   if( is_full(s))
      printf("Stack overflow");
   else
   {
	(s->top)++;
	s->arr[s->top]=val;
   }    
}
int is_empty(struct stack s)
{
    return s.top==-1;
}
char pop(struct stack *s)
{
    int val = -1;
    if(is_empty(*s))
      printf("Stack empty");
    else
     {
	int t = s->arr[s->top];
        s->top--;
        val = t;
      }
    return val;
} 
int main()
{
    char string[MAX];
    printf("Enter the string:");
    fgets(string,MAX-1,stdin);
    int l = strlen(string);/*fgets adds a new line char*/
    string[l-1]='\0';
    if(is_palindrome(string))
      printf("%s is a palindrome\n",string);
    else
      printf("%s is not a palindrome\n",string);
    return 0;
}