Infix to postfix conversion using linked list in c - c

Can anyone please help me with this code? I'm trying to convert from infix to postfix using a linked list. With an array, I can easily solve this, that solution is also similar to this one. But I'm not getting why this is not working. My guess is I've done anything wrong in this part -
if (precedence(ch) > precedence(top->data))
{
push(ch);
}
else
{
while (precedence(ch) <= precedence(top->data))
{
postfix = insert(postfix, pop());
}
push(ch);
}
Here is the complete code. Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
struct Node
{
char data;
struct Node *next;
};
struct Node *top = NULL;
struct Node *postfix = NULL;
void push(char ch);
char pop();
int is_operator(char ch);
int precedence(char ch);
void convert(char *infix);
struct Node *insert(struct Node *head, char ch);
void print(struct Node *head);
int main()
{
char infix[MAX_SIZE] = "(A+B^C)*D+E^5";
printf("Infix: %s\n", infix);
convert(infix);
printf("Postfix: ");
print(postfix);
}
void convert(char *infix)
{
int i, len = strlen(infix);
char ch;
for (i = 0; i < len; i++)
{
ch = infix[i];
if (is_operator(ch) == 0)
{
postfix = insert(postfix, ch);
}
else
{
if (ch == '(')
{
push(ch);
}
else
{
if (ch == ')')
{
while (top->data != '(')
{
postfix = insert(postfix, pop());
}
pop();
}
else
{
if (precedence(ch) > precedence(top->data))
{
push(ch);
}
else
{
while (precedence(ch) <= precedence(top->data))
{
postfix = insert(postfix, pop());
}
push(ch);
}
}
}
}
}
while (top != NULL)
{
postfix = insert(postfix, pop());
}
}
int is_operator(char ch)
{
switch (ch)
{
case '+':
case '-':
case '*':
case '/':
case '^':
case '(':
case ')':
return 1;
default:
return 0;
}
}
int precedence(char ch)
{
switch (ch)
{
case '+':
case '-':
return 2;
case '*':
case '/':
return 3;
case '^':
return 4;
default:
return 1; // if (, ), or empty
}
}
void push(char ch)
{
struct Node *newP = (struct Node *)malloc(sizeof(struct Node));
newP->data = ch;
newP->next = top;
top = newP;
}
char pop()
{
char ch = top->data;
struct Node *temp = top;
top = temp->next;
free(temp);
temp = NULL;
return ch;
}
struct Node *insert(struct Node *head, char ch)
{
struct Node *newP = (struct Node *)malloc(sizeof(struct Node));
newP->data = ch;
newP->next = NULL;
if (head == NULL)
{
head = newP;
}
else
{
struct Node *temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = newP;
}
return head;
}
void print(struct Node *head)
{
while (head != NULL)
{
printf("%c", head->data);
head = head->next;
}
printf("\n");
}

Related

Code for parenthesis matching using stack made with double linked list isn't giving any output

I was given an assignment to write the code for parenthesis matching using Double Linked Lists. So, I made stack functions using the same and even wrote the parenthesis matching function with it. But somehow, even after removing all the errors, I'm not able to run the code, i.e. it's not showing any output
Here is my code
#include <stdio.h>
#include <stdlib.h>
struct node
{
char data;
struct node *next;
struct node *prev;
}*top = NULL;
int isFull()
{
struct node *n = (struct node *)malloc(sizeof(struct node));
if (n == NULL)
{
return 1;
}
else
{
return 0;
}
}
int isEmpty(struct node *top)
{
if (top == NULL)
{
return 1;
}
else
{
return 0;
}
}
struct node *push(struct node *top, char val)
{
struct node *ptr = (struct node *)malloc(sizeof(struct node));
if (isFull())
{
printf("Stack overflowed!\n");
}
else if (isEmpty(top))
{
ptr->data = val;
ptr->next = top;
ptr->prev = NULL;
top = ptr;
return top;
}
else
{
ptr->data = val;
top->prev = ptr;
ptr->next = top;
ptr->prev = NULL;
top = ptr;
return top;
}
}
char pop(struct node **top)
{
struct node *ptr = *top;
char x;
if (isEmpty(*top))
{
printf("Stack Underflowed!\n");
}
else
{
x = (*top)->data;
((*top)->next)->prev = NULL;
*top = ptr->next;
free(ptr);
return x;
}
}
void print(struct node *start)
{
struct node *ptr = start;
while (ptr->next != NULL)
{
printf("%c ", ptr->data);
ptr = ptr->next;
}
}
int match(char a, char b)
{
if (a == '{' && b == '}')
{
return 1;
}
if (a == '[' && b == ']')
{
return 1;
}
if (a == '(' && b == ')')
{
return 1;
}
return 0;
}
int parenthesis(struct node *top, char *str)
{
char popped_char;
for (int i = 0; str[i] != '\0'; i++)
{
if (str[i] == '{' || str[i] == '[' || str[i] == '(')
{
top = push(top, str[i]);
}
else if (str[i] == '}' || str[i] == ']' || str[i] == ')')
{
popped_char = pop(&top);
if (!match(popped_char, str[i]))
{
return 0;
}
}
}
if (isEmpty(top))
{
return 1;
}
else
{
return 0;
}
}
int main()
{
// struct node *top = (struct node *)malloc(sizeof(struct node));
// top = NULL;
char *str = (char*)malloc(100*sizeof(char));
printf("Enter the string\n");
scanf("%s", str);
// printf("%s", str);
// para(top, str);
if (parenthesis(top, str))
{
printf("Parenthesis Matched!\n");
}
else
{
printf("Parenthesis did not match!\n");
}
}
If I write {} or {()}, I was expecting to get the output as "Parenthesis did not match!", but my code isn't even running.

I am trying to implement bst insertion operations in C by using double pointer but getting a segmentation fault in the code below, idk why?

I think the main problem lies with pointer also keeping in mind the restriction that I can't return node type pointer. Please help me find out where am I doing the mistake.
I have commented the other operations of this code and trying to solve this one first. So the code has switch statements and the irrelevant functions calls have been added as part of comment for now.
#include <stdio.h>
#include <stdlib.h>
typedef struct tree { //definition of structure
int info;
//char *Name;
struct tree *left;
struct tree *right;
} tree;
int main()
{
int flag;
int choice1, item;
char ch;
int main_menu(int *choice1);
int insert(tree **root, int item);
int display(tree *root);
tree *root = NULL;
while (1) {
system("clear");
main_menu(&choice1);//calling function to display original menu list
switch (choice1) {
case 1:
printf("\nEnter number to be inserted:");
scanf("%d", &item);
insert(&root, item);
break;
case 2:
//delete();
break;
case 3:
//search();
break;
case 4:
//printf("\nTerminating code.....");
display(root);
//return(1);
break;
default:
printf("\nInvalid choice!!");
break;
}
getchar();
printf("Enter y to continue");
ch = getchar();
if (ch != 'y')
break;
}
return (1);
}
int main_menu(int *choice1) {
printf("\t\tThe main menu of operations are listed below ");//showing menu
printf("\n1.insert a value.\n2.delete a value.\n3.search a value \n4.display");
printf("\n\nEnter choice:");
scanf("%d", &*choice1);//taking choice of user as input
return (1);
}
tree *getnode(int item) { //function to create node and returning node pointer
tree *p;
p = (tree *)malloc(sizeof(tree));
p->right = NULL;
p->left = NULL;
p->info = item;
return (p);
}
int insert(tree **root, int item) {
tree *ptr, *ptr1, *new;
int flag;
flag = 0;
new = getnode(item);
if (*root == NULL) {
*root = new;
(*root)->left = NULL;
(*root)->right = NULL;
} else {
ptr = *root;
while ((ptr != NULL) && (flag == 0)) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
}
if (ptr->info == item) {
flag = 1;
printf("\nalready present");
return (1);
}
if (item > ptr->info) {
ptr = ptr->right;
}
}
/*if (ptr == NULL) {
new = getnode(item);
}*/
if (ptr1->info < item) {
ptr1->right = new;
} else {
ptr1->left = new;
}
}
return (1);
}
The problem is in the while loop descending the tree: you should add else clauses so the next if test is not evaluated with the updated value of ptr:
while ((ptr != NULL) && (flag == 0)) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
} else
if (ptr->info == item) {
flag = 1;
printf("\nalready present");
return (1);
} else
if (item > ptr->info) {
ptr = ptr->right;
}
}
Note that the flag indicator is redundant as you return directly from the while loop body when you set it to 1.
Note also that the prototypes for the functions called from main should be outside of the body of main so they are visible when the functions are defined and any conflicts can be detected by the compiler.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct tree {
int info;
//char *Name;
struct tree *left;
struct tree *right;
} tree;
int main_menu(int *choice1);
int insert(tree **root, int item);
int display(tree *root);
// read and discard the rest of the input line
// return EOF at end of file
int flush_input(void) {
int ch;
while ((ch = getchar()) != EOF && ch != '\n')
continue;
return ch;
}
int main() {
int flag, choice1, item, ch;
tree *root = NULL;
for (;;) {
system("clear");
main_menu(&choice1); //calling function to display original menu list
switch (choice1) {
case 1:
printf("\nEnter number to be inserted: ");
if (scanf("%d", &item) != 1) {
flush_input();
break;
}
flush_input();
insert(&root, item);
break;
case 2:
//delete();
break;
case 3:
//search();
break;
case 4:
//printf("\nTerminating code.....");
display(root);
//return(1);
break;
default:
printf("\nInvalid choice!!");
break;
}
printf("Enter y to continue: ");
/* read and discard the rest of the input line */
ch = getchar();
flush_input()
if (ch != 'y')
break;
}
return 0;
}
int main_menu(int *choice1) {
printf("\t\tThe main menu of operations are listed below ");//showing menu
printf("\n1.insert a value.\n2.delete a value.\n3.search a value \n4.display");
printf("\n\nEnter choice:");
*choice1 = -1; //default input incase of scanf failure
scanf("%d", choice1); //taking choice of user as input
flush_input(); // discard rest of the line
return 1;
}
tree *getnode(int item) { //function to create node and returning node pointer
tree *p = (tree *)malloc(sizeof(tree));
p->right = NULL;
p->left = NULL;
p->info = item;
return p;
}
int insert(tree **root, int item) {
tree *new, *ptr, *ptr1;
ptr1 = ptr = *root;
while (ptr != NULL) {
ptr1 = ptr;
if (item < ptr->info) {
ptr = ptr->left;
} else
if (item > ptr->info) {
ptr = ptr->right;
} else {
printf("\nalready present\n");
return 1;
}
}
new = getnode(item);
if (ptr1 == NULL) {
*root = new;
} else
if (ptr1->info < item) {
ptr1->right = new;
} else {
ptr1->left = new;
}
return 1;
}

® (\256) character in c++

what does ® mean in c language and in this codes give an error that [Error] stray '\256' in program in the print part because of ® . And ı
wanna translate c++ code. While that, ım taken [Error] invalid conversion from 'void*' to 'node*' [-fpermissive]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 10
#define EMPTY -1
struct node
{
char kind;
char op;
int number;
struct node *left,*right;
};
struct stack
{
struct node *data[MAX];
int top;
};
int isempty(struct stack *s)
{
return (s->top == EMPTY) ? 1 : 0;
}
void emptystack(struct stack* s)
{
s->top=EMPTY;
}
void push(struct stack* s, struct node *item)
{
if(s->top == (MAX-1))
{
printf("\nSTACK FULL");
}
else
{
++s->top;
s->data[s->top]=item;
}
}
struct node* pop(struct stack* s)
{
struct node *ret=NULL;
if(!isempty(s))
{
ret= s->data[s->top];
--s->top;
}
return ret;
}
void postfix2exptree(char* postfix, struct node **root)
{
struct stack X;
struct node *newnode,*op1,*op2;
char numberextract[5];
char *p;
emptystack(&X);
p = &postfix[0];
strcpy(numberextract,"");
while(*p)
{
while(*p == ' ' || *p == '\t')
{
p++;
}
if(isdigit(*p))
{
while(isdigit(*p))
{
strcat(numberextract,p);
p++;
}
newnode = malloc(sizeof(struct node));
newnode->kind = 'N';
newnode->number = atoi(numberextract);
newnode->left = NULL;
newnode->right = NULL;
push(&X,newnode);
strcpy(numberextract,"");
}
else
{
op1 = pop(&X);
op2 = pop(&X);
newnode = malloc(sizeof(struct node));
newnode->kind = 'O';
newnode->op = *p;
newnode->left = op2;
newnode->right = op1;
push(&X,newnode);
}
p++;
}
*root = pop(&X);
}
int evaluatetree(struct node *x)
{
if( x->kind == 'O' )
{
int op1 = evaluatetree( x->left );
int op2 = evaluatetree( x->right );
switch ( x->op )
{
case '+': return op1 + op2;
case '-': return op1 - op2;
case '*': return op1 * op2;
case '/': return op1 / op2;
default: return 0;
}
}
else
return (x->number);
}
void inorder(struct node *x)
{
if(x != NULL)
{
inorder(x->left);
if(x->kind == 'O')
printf("%c ",x->op);
else
printf("%d ",x->number);
inorder(x->right);
}
}
void preorder(struct node *x)
{
if(x != NULL)
{
if(x->kind == 'O')
printf("%c ",x->op);
else
printf("%d ",x->number);
preorder(x->left);
preorder(x->right);
}
}
void postorder(struct node *x)
{
if(x != NULL)
{
postorder(x->left);
postorder(x->right);
if(x->kind == 'O')
printf("%c ",x->op);
else
printf("%d ",x->number);
}
}
int main()
{
struct node *r;
postfix2exptree("100 50 - 2 /",&r);
printf("Inorder = ");
*inorder®;
printf("\nPreorder = ");
preorder®;
printf("\nPostprder = ");
postorder®;
printf("\nResult = %d\n",evaluatetree®);
return 0;
}
This is an artefact of "smart" text editors.
The code is supposed to read:
inorder(r);
printf("\nPreorder = ");
preorder(r);
where r is a struct node *.
The original author pasted the text and didn't check, smart text editing transformed (r) into the copyright sign.
Note that inorder and preorder are functions defined earlier in the code.

postfix calculator having trouble with segfaults

i'm trying to create a postfix calculator using linked-list.
when i compile, it doesn't show any errors but when it's executed it would show Segmentation Fault. i don't know how to deal with this, please help.
here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct node {
int num;
struct node *next;
} node;
void push(int num, node **head);
int pop(node **head);
void display(node **head);
int is_empty();
int evaluatePostfix();
struct node *head;
int main() {
head = NULL;
char exp[1000]; // = "5 1 2 + 4 * + 3 -";
printf("Input expression:\t");
fgets(exp, 1000, stdin);
for(int i = 1; i <= strlen(exp); i++) {
if(exp[i] == '\n') {
exp[i] = '\0';
}
else if (exp[0] == '\n') {
printf("stack is empty\n");
exit(0);
}
}
printf("%s = %d\n", exp, evaluatePostfix(exp));
return 0;
}
int evaluatePostfix(char* exp) {
char * token;
int counter = 0;
char temp[256][256];
token = strtok(exp, " ");
while(token != NULL) {
strcpy(temp[counter], token);
counter++;
token = strtok(NULL, " ");
}
for (int i = 0; temp[i]; ++i) {
if (isdigit(*(temp[i]))) {
int val = atoi(temp[i]);
push(val, &head);
}
else {
int val1 = pop(&head);
int val2 = pop(&head);
switch (exp[i]) {
case '+': push(val2 + val1, &head);
printf("%d\n", (*head).num);
break;
case '-': push(val2 - val1, &head); break;
case '*': push(val2 * val1, &head); break;
case '/': push(val1 / val2, &head); break;
}
}
}
return pop(&head);
}
void push (int item, node **head) {
node *temp;
node * get_node(int);
temp = get_node(item);
temp->next = *head;
*head = temp;
}
node *get_node(int item) {
node *temp;
temp = (node*)malloc(sizeof(node));
if (temp == NULL)
printf("\nMemory cannot be allocated");
temp->num = item;
temp->next = NULL;
return(temp);
}
int pop(node **head) {
int item;
node *temp;
item = (*head)->num;
temp = *head;
*head = (*head)->next;
free(temp);
return(item);
}
int is_empty(node *temp) {
if (temp == NULL)
return 1;
else
return 0;
}
void display(node **head) {
node *temp;
temp = *head;
if(head == NULL) {
printf("stack is empty\n");
return;
}
printf("\n");
printf("=========\n");
while(temp!=NULL) {
printf("%d\n", (*temp).num);
temp = (*temp).next;
}
printf("=========\n");
}
Given this declaration ...
char temp[256][256];
... the loop termination condition here is wrong:
for (int i = 0; temp[i]; ++i) {
C multi-dimensional arrays are not Java-style arrays of array references. They are arrays of actual arrays. The expression temp[i] will not be false when i exceeds the number of elements of temp[] into which you have written data.
It looks like you want simply
for (int i = 0; i < counter; ++i) {
. Alternatively, there's no particular need to tokenize before your start the computation. You could as easily combine the two loops in function evaluatePostfix() into one. That would be a bit simpler, and would remove any fixed limit on the number of terms in the expression.
Update: That might look like this:
for (token = strtok(exp, " "); token; token = strtok(NULL, " ")) {
/* ... use token instead of temp[i] ... */
}
It is conceivable that there are other errors in your code as well, though I didn't spot any on my scan through it.
"btw, all identifiers for functions in the Standard Library are reserved.
There is a function exp() in math.h, so exp falls into that category.
Technically, using a reserved identifier in your code results in undefined behaviour."
Thanks for the help guys! Changing exp to another variable name did the trick. here's the working code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct node {
int num;
struct node *next;
} node;
void push(int num, node **head);
int pop(node **head);
void display(node **head);
int is_empty(node *temp);
int evaluate(char *expression);
struct node *head;
int main() {
head = NULL;
char expression[1000]; // = "5 1 2 + 4 * + 3 -";
printf("Input expression:\t");
fgets(expression, 1000, stdin);
for(int i = 1; i <= strlen(expression); i++) {
if(expression[i] == '\n') {
expression[i] = '\0';
}
else if (expression[0] == '\n') {
printf("empty stack\n");
exit(0);
}
}
printf("Answer: %d\n", evaluate(expression) );
return 0;
}
int evaluate(char* expression) {
char * token;
int counter = 0;
char temp[256][256];
token = strtok(expression, " ");
while(token != NULL) {
strcpy(temp[counter], token);
token = strtok(NULL, " ");
counter++;
}
for (int i = 0; i < counter; i++) {
if (isdigit(*(temp[i]))) {
int val = atoi(temp[i]);
push(val, &head);
}
else {
int val1 = pop(&head); //pop the last two values from stack
int val2 = pop(&head);
switch (*(temp[i])) { //perform operation
case '+': push(val2 + val1, &head); break;
case '-': push(val2 - val1, &head); break;
case '*': push(val2 * val1, &head); break;
case '/': push(val1 / val2, &head); break;
}
}
}
return pop(&head);
}
void push (int item, node **head) {
node *temp;
node * get_node(int);
temp = get_node(item);
temp->next = *head;
*head = temp;
}
node *get_node(int item) {
node *temp;
temp = (node*)malloc(sizeof(node));
if (temp == NULL)
printf("\nMemory cannot be allocated");
temp->num = item;
temp->next = NULL;
return(temp);
}
int pop(node **head) {
int item;
node *temp;
item = (*head)->num;
temp = *head;
*head = (*head)->next;
free(temp);
return(item);
}
int is_empty(node *temp) {
if (temp == NULL)
return 1;
else
return 0;
}
void display(node **head) {
node *temp;
temp = *head;
if(head == NULL) {
printf("stack is empty\n");
return;
}
printf("\n");
printf("=========\n");
while(temp!=NULL) {
printf("%d\n", (*temp).num);
temp = (*temp).next;
}
printf("=========\n");
}

Infix to postfix implementation using linked lists

I've been trying to debug this program for a long time. It works fine when I input expressions like a + b - c or a / b + c where the first operator has a greater or equal precedence than the second. But for expressions like a - b / c where the first operator has a lesser precedence than the second, the compiler throws a breakpoint.
struct stack
{
char ele;
struct stack *next;
};
void push(int);
int pop();
int precedence(char);
struct stack *top = NULL;
int main()
{
char infix[20], postfix[20];
int i = 0, j = 0;
printf("ENTER INFIX EXPRESSION: ");
gets(infix);
while(infix[i] != '\0')
{
if(isalnum(infix[i]))
postfix[j++] = infix[i];
else
{
if(top == NULL)
push(infix[i]);
else
{
while( top != NULL &&
(precedence(top->ele) >= precedence(infix[i])) )
postfix[j++]=pop();
push(infix[i]);
}
}
++i;
}
while(top != NULL)
postfix[j++] = pop();
postfix[j] = '\0';
puts(postfix);
getchar();
return 0;
}
int precedence(char x)
{
switch(x)
{
case '^': return 4;
case '*':
case '/': return 3;
case '+':
case '-': return 2;
default: return 0;
}
}
void push(int x)
{
int item;
struct stack *tmp;
if(top == NULL)
{
top = (struct stack *)malloc(sizeof(struct stack));
top->ele = x;
top->next = NULL;
}
else
{
tmp = top;
top->ele = x;
top->next = tmp;
}
}
int pop()
{
struct stack *tmp;
int item;
if(top == NULL)
puts("EMPTY STACK");
else if(top->next == NULL)
{
tmp = top;
item = top->ele;
top = NULL;
free(tmp);
}
else
{
tmp = top;
item = top->ele;
top = top->next;
free(tmp);
}
return item;
}
Any advice on how to improve my coding would be helpful.

Resources