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;
}