implementing stack with linked list in C - c

I'm having trouble implementing a Stack using a linked list with struct. The program compiles fine but when I run it, it prints the first element but then reads the next node as a NULL. I think it might be an error with my passing of the stack to the push method but I am not sure and I have not been successful in fixing it so I'm asking for your help:
#include <stdio.h>
#include <stdlib.h>
struct stackNode{
char data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
void convertToPostfix(char infix[], char postfix[]);
int isOperator(char c);
int precedence(char operator1, char operator2);
void push(StackNodePtr *topPtr, char value);
char pop(StackNodePtr *topPtr);
char stackTop(StackNodePtr topPtr);
int isEmpty(StackNodePtr topPtr);
void printStack(StackNodePtr topPtr);
int main(){
convertToPostfix(NULL, NULL);
return 0;
}
void convertToPostfix(char infix[], char postfix[]){
StackNode stack = {'(', NULL};
StackNodePtr stackPtr = &stack;
push(stackPtr, 'a');
//printf("%s\n", stackPtr->data);
printStack(&stack);
}
void push(StackNodePtr *topPtr, char value){
StackNode *node;
node=(StackNodePtr)malloc(sizeof(StackNodePtr));
node->data=value;
node->nextPtr=*topPtr;
*topPtr=node;
}
void printStack(StackNodePtr topPtr){
if(topPtr == NULL){
printf("%s\n", "NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO");
return;
}
printf("%c\n", topPtr->data);
printStack(topPtr->nextPtr);
}
Any help would be appreciated.
Thanks

Several problems I could see:
1) printStack(&stack); should be printStack(stackPtr); as you are passing address of stackPtr to the push function.
2)
node = (StackNodePtr)malloc(sizeof(StackNodePtr));
should be:
node = malloc(sizeof(StackNode));
3)
push(stackPtr, 'a');
should be:
push(&stackPtr, 'a');
As you need to pass the address of the top pointer.

This is incorrect:
node=(StackNodePtr)malloc(sizeof(StackNodePtr));
as it is only allocating memory for a struct stackNode* (commonly 4-bytes for any pointer type), when it should be allocating memory for a struct stackNode (at least 5 bytes):
node = malloc(sizeof(StackNode));
--
See Do I cast the result of malloc?

#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node * link;
};
void push(struct node **, int);
int pop(struct node **);
void display(struct node *);
void printMenu();
int main() {
struct node * p;
p = NULL;
int data, ch, data1;
//char choice[10];
do {
printMenu();
printf("Enter your choice\n");
scanf("%d", &ch);
switch (ch) {
case 1:
printf("Enter the element to be pushed\n");
scanf("%d", &data);
push(&p, data);
break;
case 2:
data1 = pop(&p);
if (data1 != -1000)
printf("The popped element is %d\n", data1);
break;
case 3:
printf("The contents of the stack are");
display(p);
printf("\n");
break;
default:
return 0;
}
} while (1);
return 0;
}
void printMenu() {
printf("Choice 1 : Push\n");
printf("Choice 2 : Pop\n");
printf("Choice 3 : Display\n");
printf("Any other choice : Exit\n");
}
void push(struct node **q, int num) {
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->link = (*q);
temp->data = num;
(*q) = temp;
}
void display(struct node *q) {
//Fill in the code here
struct node *temp = q;
if (temp == NULL)
printf(" {}");
while (temp != NULL)
{
printf(" %d", temp->data);
temp = temp->link;
}
}
int pop(struct node **q) {
//Fill in the code here
struct node *temp;
int item;
if (*q == NULL)
{
printf("Stack is empty\n");
return -1000;
}
temp = *q;
item = temp->data;
*q = (*q)->link;
free(temp);
return item;
}

Related

Weird string value when I return a string value from a node when I dequeue a linked list implementation

The program is not complete. I can add enqueue nodes, display the list of nodes, and find the top of the node, etc... But when I try to dequeue and return a node from the dequeue function the customer's name gets jumbled up. This is a queue implementation in linked list. The application is similar to an order system from a fast-food chain.
Also, I was expected to have this operation in my program:
"INIT(): creates and returns an empty queue."
Did I do it right?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLENGTH 20
struct Node{
char name[MAXLENGTH];
char order[MAXLENGTH];
struct Node* link;
};
struct Node* Init();
int Empty(struct Node*, struct Node*);
struct Node* Front(struct Node*);
void AskOrder(struct Node**, struct Node**);
void EnQueue(char*, char* , struct Node** , struct Node** );
struct Node* DeQueue(struct Node**, struct Node** );
void display(struct Node* );
int main()
{
struct Node* front = NULL;
struct Node* rear = NULL;
int ch = -1;
struct Node* printme = NULL;
while(ch!=0)
{
printf("ORDER LIST:");
if (Empty(front, rear) != 1)
display(front);
printf("\n\nJohn's Store Menu:\n"
"\n [1] Fall in line"
"\n [2] Serve order"
"\n [3] Next order"
"\n [4] Closing time"
"\n [0] Exit\n"
"\nEnter choice: ");
scanf("%d", &ch);
switch(ch)
{
case 1:
AskOrder(&front, &rear);
break;
case 2:
if(Empty(front, rear) != 1)
{
printme = DeQueue(&front, &rear);
printf("\nNow serving [%s] to customer [%s].\n", printme->order, printme->name);
}else
printf("The QUEUE is EMPTY. No orders to serve.");
break;
case 3:
if(Empty(front, rear) != 1)
{
printme = Front(front);
printf("\nNext order: [%s] of customer [%s].\n", printme->order, printme->name);
}else
printf("The QUEUE is EMPTY. No orders to serve.\n");
break;
case 4:
if(Empty(front, rear) != 1)
{
}else
printf("The QUEUE is EMPTY. No orders to serve.\n");
break;
case 0:
printf("\nOrder system has been terminated.\n");
return 0;
default:
printf("Invalid choice.\n");
break;
}
system("pause");
system("cls");
}
}
struct Node* Init()
{
struct Node* q = (struct Node*)malloc(sizeof(struct Node));
q->link = NULL;
return q;
}
int Empty(struct Node* fr, struct Node* rr)
{
if(fr == NULL && rr == NULL)
{
return 1;
}else{
return 0;
}
}
struct Node* Front(struct Node* fr)
{
return fr;
}
void AskOrder(struct Node** front, struct Node** rear)
{
char name[MAXLENGTH];
char order[MAXLENGTH];
printf("\nWhat's your name? ");
fflush(stdin);
gets(name);
printf("What's your order? ");
fflush(stdin);
gets(order);
EnQueue(name, order, front, rear);
}
void EnQueue(char* nm, char* ordr, struct Node** fr, struct Node** rr)
{
struct Node* temp = Init();
strcpy(temp->name, nm);
strcpy(temp->order, ordr);
if(Empty(*fr, *rr) == 1)
{
*fr = *rr = temp;
return;
}
(*rr)->link = temp;
*rr = temp;
}
struct Node* DeQueue(struct Node** fr, struct Node** rr)
{
struct Node* printme = *fr;
struct Node* temp = *fr;
if(*fr == *rr){
*fr = *rr = NULL;
}else{
*fr = (*fr)->link;
}
free(temp);
return printme;
}
void display(struct Node* fr){
while(fr != NULL)
{
printf("\n[%s] of customer [%s]", fr->order, fr->name);
fr = fr->link;
}
}

How can I create this linked list with stack in C?

I can create the linked list. But I could not managed to create the stack with it. (Stack cannot be more than 5, and it can be empty as shown in the link). How can I do it? (C language but C++ functions like new int are allowed)
The structure could be something like:
struct linkedStack {
int elements[5];
int top;
struct linkedStack *next;
};
Then manage the stack with top (equals to zero at the beginning)...
Post your code please so we can understand what you are trying to make.
This example can help you
#include<stdio.h>
#include<conio.h>
#include<process.h>
#include<stdlib.h>
#include<alloc.h>
void Push(int, node **);
void Display(node **);
int Pop(node **);
int Sempty(node *);
typedef struct stack {
int data;
struct stack *next;
} node;
void main() {
node *top;
int data, item, choice;
char ans, ch;
clrscr();
top = NULL;
printf("\nStack Using Linked List : nn");
do {
printf("\n\n The main menu");
printf("\n1.Push \n2.Pop \n3.Display \n4.Exit");
printf("\n Enter Your Choice");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("\nEnter the data");
scanf("%d", &data);
Push(data, &top);
break;
case 2:
if (Sempty(top))
printf("\nStack underflow!");
else {
item = Pop(&top);
printf("\nThe popped node is%d", item);
}
break;
case 3:
Display(&top);
break;
case 4:
printf("\nDo You want To Quit?(y/n)");
ch = getche();
if (ch == 'y')
exit(0);
else
break;
}
printf("\nDo you want to continue?");
ans = getche();
getch();
clrscr();
} while (ans == 'Y' || ans == 'y');
getch();
}
void Push(int Item, node **top) {
node *New;
node * get_node(int);
New = get_node(Item);
New->next = *top;
*top = New;
}
node * get_node(int item) {
node * temp;
temp = (node *) malloc(sizeof(node));
if (temp == NULL)
printf("\nMemory Cannot be allocated");
temp->data = item;
temp->next = NULL;
return (temp);
}
int Sempty(node *temp) {
if (temp == NULL)
return 1;
else
return 0;
}
int Pop(node **top) {
int item;
node *temp;
item = (*top)->data;
temp = *top;
*top = (*top)->next;
free(temp);
return (item);
}
void Display(node **head) {
node *temp;
temp = *head;
if (Sempty(temp))
printf("\nThe stack is empty!");
else {
while (temp != NULL) {
printf("%d\n", temp->data);
temp = temp->next;
}
}
getch();
}

pointer to a struct becomes NULL at every function call

The problem is that every time the function addNodePos is being called head pointer is NULL (saw that in debugger), and it just creates a list of one node, which points to itself as it is a circular doubly-linked list. And it displays "List is empty." because list is also NULL, when passing to a printList function. Have been trying to understand why but still there is no result.
Here is the code (removed excessive code according to SSCCE)
#include <stdio.h>
#include <stdlib.h>
struct DoubleList
{
int id;
struct DoubleList *next;
struct DoubleList *prev;
};
void addNodePos(struct DoubleList* head, int value, int position);
void printList (struct DoubleList* head);
//void clearList (struct DoubleList* head);
int main()
{
int value, position;
struct DoubleList *list = NULL;
printf("\nvalue: ");
scanf("%x", &value);
printf("position: ");
scanf("%d", &position);
addNodePos(list, value, position);
printf("\nvalue: ");
scanf("%x", &value);
printf("position: ");
scanf("%d", &position);
addNodePos(list, value, position);
printList(list);
//clearList(list);
return 0;
}
void addNodePos(struct DoubleList* head, int value, int position)
{
int i;
struct DoubleList *node;
if ( (node = malloc (sizeof(struct DoubleList))) != NULL ){
node->id=value;
if (head==NULL) {
// points to itself as it is the only node in a list
node->next=node;
node->prev=node;
head=node;
} else {
struct DoubleList *current=head;
for (i = position; i > 1; i--)
current=current->next;
// reassign pointers -- relink nodes
current->prev->next=node;
node->prev=current->prev;
node->next=current;
current->prev=node;
}
}
printf("Element has been added.\n\n");
}
void printList(struct DoubleList* head)
{
if (head==NULL)
printf("\nList is empty.\n\n");
else {
struct DoubleList *current=head;
printf("\nThe list: ");
do {
printf("%d", current->id);
current=current->next;
if(current != head)
printf("<->");
} while(current!=head);
printf("\n\n");
}
}
The address of head is passed by value, so your changes are only reflected in the function itself. You have to pass a pointer to the address of head so that you can change the value.
int main() {
...
addNodePos(&list, value, position);
...
}
void addNodePos(struct DoubleList** headPtr, int value, int position)
{
struct DoubleList *head = *headPtr;
int i;
struct DoubleList *node;
if ( (node = malloc (sizeof(struct DoubleList))) != NULL ){
node->id=value;
if (head==NULL) {
// points to itself as it is the only node in a list
node->next=node;
node->prev=node;
head=node;
} else {
struct DoubleList *current=head;
for (i = position; i > 1; i--)
current=current->next;
// reassign pointers -- relink nodes
current->prev->next=node;
node->prev=current->prev;
node->next=current;
current->prev=node;
}
}
printf("Element has been added.\n\n");
}
With a great help of users (which shared some very useful links), I have managed solving it.
Solution: to modify caller memory, pass a pointer to that memory.
After a bit updating, I leave here correctly working code:
#include <stdio.h>
#include <stdlib.h>
struct DoubleList
{
int id;
struct DoubleList *next;
struct DoubleList *prev;
};
void addNodePos(struct DoubleList** headRef, int value, int position);
void printList (struct DoubleList** headRef);
//void clearList (struct DoubleList** headRef);
int main()
{
int value, position;
struct DoubleList *list = NULL;
printf("\nvalue: ");
scanf("%x", &value);
printf("position: ");
scanf("%d", &position);
addNodePos(&list, value, position);
printf("\nvalue: ");
scanf("%x", &value);
printf("position: ");
scanf("%d", &position);
addNodePos(&list, value, position);
printList(&list);
//clearList(head);
return 0;
}
void addNodePos(struct DoubleList** headRef, int value, int position)
{
int i;
struct DoubleList *node;
if ( (node = malloc (sizeof(struct DoubleList))) != NULL ){
node->id=value;
if ( (*headRef)==NULL) {
// points to itself
node->next=node;
node->prev=node;
(*headRef)=node;
} else {
struct DoubleList *current=(*headRef);
for (i = position; i > 1; i--)
current=current->next;
// reassign pointers -- relink nodes
current->prev->next=node;
node->prev=current->prev;
node->next=current;
current->prev=node;
}
}
printf("Element has been added.\n\n");
}
void printList(struct DoubleList** headRef)
{
if ( (*headRef)==NULL)
printf("\nList is empty.\n\n");
else {
struct DoubleList *current=(*headRef);
printf("\nThe list: ");
do {
printf("%x", current->id);
current=current->next;
if(current != (*headRef))
printf("<->");
} while(current!=(*headRef));
printf("\n\n");
}
}

Queue Implementation using two stacks-Pointers Incompatibility Error

The program task is to implement a queue using two stacks.I understand that pointers need to be passed as parameters like this - pop(**&**headA). But when I do that, I get an 'incompatible pointer' compile time error. So, when I execute the code like shown below, I get logical error. It doesn't run the way I want it to.
#include<stdio.h>
typedef struct node{
int data;
struct node *link;
}node;
node *headA = NULL;
node *headB = NULL;
void push(node *,int);
int pop(node *);
void display(node *);
void enQ();
void dQ();
main(){
int choice;
system("cls");
printf("\n\tWelcome to Queue implementation using two stacks.\n");
do{
/* Menu */
printf("\n\tWhat would you like with your queue?\n\n");
printf("1. Insert an element at the front (EnQ)\n2. Delete the last element (DQ)\n3. Exit program\n\nEnter your desired choice with the corresponding serial number :\n\n");
scanf("%d",&choice);
system("cls");
switch(choice){
case 1: enQ();
break;
case 2: dQ();
break;
case 3: printf("\n\tSorry to see you go, hope to see you back soon!\n");
exit(0);
default: printf("\n\tSorry, That option is unavailable. Try again!\n\n");
}
}while (choice >= 0);
}
void enQ(){
int add;
int x,y;
printf("\n\tEnter the item\n");
scanf("%d",&add);
if(headB == NULL){
push(headA, add);
}
else{
while(headB != NULL){
x = pop(headB);
push(headA, x);
}
push(headA, add);
}
while(headA != NULL){
y = pop(headA);
push(headB, y);
}
display(headB);
}
void dQ(){
int del;
int x,y;
if(headB == NULL){
printf("Queue is empty.");
}
else{
while(headB != NULL){
x = pop(headB);
push(headA, x);
}
del = pop(headA);
printf("\n\tThe element deleted is : %d ", del);
while(headA != NULL){
y = pop(headA);
push(headB, y);
}
display(headB);
}
}
void push(node *head, int add){
node *last_node;
last_node = (node*)malloc(sizeof(node));
last_node->data = add;
last_node->link = head;
head = last_node;
}
int pop(node *head){
node *last_node;
int flag = 0;
if(head==NULL)
return flag;
else{
last_node = head;
flag = last_node->data;
head = head->link;
free(last_node);
return flag;
}
}
void display(node *head){
node *my_stack;
if(head == NULL)
printf("\n\tStack is empty\n");
else{
my_stack = head;
printf("\n\tThe elements of the queue are : \n\n\t");
while(my_stack != NULL){
printf("%d\t", my_stack->data);
my_stack = my_stack->link;
}
}
}
int pop(node *head); What is the type of head?
node *headA = NULL; What is the type of headA?
y = pop(&headA); What is the type of &headA?
It should be clear from this that if you want to pass a node ** to pop, you need to declare pop to have a node ** argument: int pop(node **head);
int pop(node **head){
node *last_node;
int flag = 0;
if(*head==NULL)
return flag;
else{
last_node = *head;
flag = last_node->data;
*head = last_node->link;
free(last_node);
return flag;
}
}
You'll want to make this change for push, too, since that changes head, and you want those changes to be visible once push returns: void push(node **head, int add);
void push(node **head, int add){
node *last_node;
last_node = malloc(sizeof *last_node); // don't cast malloc. #include <stdlib.h> and use a C compiler rather than a C++ compiler.
last_node->data = add;
last_node->link = *head;
*head = last_node;
}

Implementation of Stack by linked list

I am getting below error message.
Could not able to solve it. Googled a lot. Finally thought of to put it here.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
int stop;
struct stack
{
int data;
struct stack *next;
};
typedef struct stack *node, *top;
//typedef struct stack *top;
void push()
{
int i;
struct stack *x;
x = malloc(sizeof(struct stack));
printf("\n Enter the element your want to insert");
scanf("%d", &i);
x->data = i;
x->next = top;
top = x;
}
void pop()
{
int i;
if(top == NULL)
{
printf("\nStack is empty\n");
}
else{
i = top->data;
free(top);
top = top->next;
}
}
void display()
{
if(node != NULL)
{
printf("%d ", node->data);
node = node->next;
}
}
int main()
{
int ch;
while(1)
{
printf("\nEnter your option \n1. Insert(Push) \n2. Delete(Pop) \n3. Display : \n");
scanf("%d", &ch);
switch(ch)
{
case 1:
push();
break;
case 2:
pop();
break;
case 3:
display();
break;
default:
printf("Invalid Entery, Try Again");
}
}
return 0;
}
remove typedef and all will be fine.
You don't want a new type:
typedef struct stack *node, *top;
Instead, you want a new variable:
struct stack *node, *top;
You cannot combine variable declarations with typedef. If you would like to create an alias for struct stack and call it simply stack, modify your code as follows:
struct stack {
int data;
struct stack *next;
};
typedef struct stack stack;
stack *node, *top;

Resources