Empty stack of linked list - c

I am trying to figure the way to empty stack for linked list. I found a way but this way is only work for array stack
void empty(StackPtr S)
{
S -> top = -1;
}
my guess is to use
while(!isEmpty(s))
which the function isEmpty will check if the stack is empty or not. Then I'm stuck :(
Edit:
The way I push it:
void push(StackPtr S, StackData d) /*adds the top element*/
{
NodePtr np = (NodePtr)malloc(sizeof(Node));
np -> data = d;
np -> next = S -> top;
S -> top = np;
}

This is a basic program for implementing stack data structure and its operations. Hope it will help you.
#include<stdio.h>
#include<stdlib.h>
#define INT_MIN -99;
struct Stack{
int data;
struct Stack *next;
};
struct Stack *CreateStack(){
return NULL;
}
void Push(struct Stack **top,int data){
struct Stack *temp;
temp=malloc(sizeof(struct Stack));
if(!temp)
return NULL;
temp->data = data;
temp->next= *top;
*top=temp;
}
int IsEmptyStack(struct Stack *top){
return top==NULL;
}
int Pop(struct Stack **top){
int data;
struct Stack *temp;
if(IsEmptyStack(*top))
return INT_MIN;
temp=*top;
*top=temp->next;
data=temp->data;
printf("%d",data);
free(temp);
return data;
}
int Top(struct Stack *top){
if(IsEmptyStack(top))
return INT_MIN;
return top->next->data;
}
void DeleteStack(struct Stack **top)
{
struct Stack *temp,*p;
p=*top;
while(p->next){
temp=p->next;
p->next=temp->next;
free(temp);
}
free(p);
}
void main(){
struct Stack *s=CreateStack();
Push(&s,5);
Push(&s,15);
Push(&s,52);
Pop(&s);
Pop(&s);
Push(&s,35);
Push(&s,53);
Pop(&s);
Push(&s,45);
}

Related

What is wrong in the stack implementation using linked lists?

I am trying to implement a stack using linked list. Here is my code:
#include<stdio.h>
//implementation of stack
struct Node{
int data;
struct Node* next;
struct Node* prev;
};
struct Stack{
struct Node* headNode;
struct Node* presentNode;
int size;
};
struct Node* newNode()
{
struct Node* node;
return node;
}
struct Stack* newStack()
{
struct Stack* stack;
stack->headNode = newNode();
stack->presentNode = stack->headNode;
stack->size=0;
return stack;
}
int isempty(struct Stack* s)
{
if(s->headNode->next != NULL)
return 0;
return 1;
}
void push(struct Stack* s,int data)
{
struct Node* node = newNode();
node->data = data;
node->next = NULL;
s->presentNode->next = node;
node->prev = s->presentNode;
s->presentNode = node;
s->size ++;
}
int pop(struct Stack*s)
{
if(isempty(s)==1)
return 0;
int data = s->presentNode->data;
s->presentNode->prev->next = NULL;
s->presentNode = s->presentNode->prev;
s->size --;
return data;
}
int main()
{
struct Stack* stack = newStack();
int data = 0,type;
printf("Enter '1' if new element to be added or '0' if the latest element is to be deleted.\n");
while(data!=-1)//unbounded stack
//takes input until data==-1
{
scanf("%d",&type);
if(type)
{
printf("Enter the element:\t");
scanf("%d",&data);
if(data==-1)
continue;
push(stack,data);
}
else
printf("%d is popped out of the list!\n",pop(stack));
}
return 0;
}
But I am getting run-time error. Since I am new to pointers (I am a Java guy), I am pretty confused where my error is, although I am sure it is due to pointers.
You do not allocate memory for your new nodes:
struct Node* newNode()
{
struct Node* node;
return node;
}
Local variable node is an uninitialized pointer. As soon as you use the return value of this function, you have Undefined Behaviour.
Edit:
The same problem is true for newStack:
struct Stack* newStack()
{
struct Stack* stack;
stack->headNode = newNode();
...
return stack;
}
As soon as you dereference stack, you have Undefined Behaviour.
You have multiple problems. For starters
In your newStack() function, you do not have a return statement, so using the return value causes undefined behavior.
You need to allocate memory to pointers (i.e., make pointers to point to valid memory) before you can actually dereference them. In your case
struct Stack* stack;
stack->headNode
is an attempt to use uninitialized memory which again causes UB.

Pop head element in stack C

I am having trouble implementing a function that deletes the first element from a stack. (I know for sure that the stack has minimum two elements)
typedef struct Node {
T value;
struct Node *next;
} Node;
typedef struct Stack {
Node *head;
} Stack;
void Pop(Stack **st) {
if (!IsEmptyStack(*st)) {
Node* aux = (*st)->head;
(*st)->head = (*st)->head->next;
}
}
but same happens... Segmentation fault.
How can I fix the pop function?
Here are the other functions i'm using:
void InitStack(Stack **st)
{
(*st) = (Stack *) malloc(sizeof(Stack *));
(*st)->head = NULL;
}
int IsEmptyStack (Stack *st)
{
if (!st)
return 1;
else
return 0;
}
The first approach seems correct, but why do you pass a double pointer to the Stack to function Pop? It seems Pop could be simplified this way:
typedef struct Node {
T value;
struct Node *next;
} Node;
typedef struct Stack {
Node *head;
} Stack;
void Pop(Stack *st) {
if (!IsEmptyStack(st)) {
Node *aux = st->head;
st->head = aux->next;
... // dispose of aux appropriately
}
}
IsEmptyStack was wrong..
instead of
int IsEmptyStack (Stack *st)
{
if (!st)
return 1;
else
return 0;
}
I have to use
int IsEmptyStack (Stack *st)
{
if (!st->head)
return 1;
else
return 0;
}
That's because i've already allocated memory for st .. so checking st is irrelevant.

Palindrome LinkedList

Method:
Traverse the given list from head to tail and push every visited node to stack.
Traverse the list again. For every visited node, pop a node from stack and compare data of popped node with currently visited node.
If all nodes matched, then return true, else false.
Edit: The program compiles without an error but stops working during run time
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
struct Node
{
int data;
struct Node *next;
};
struct Stack
{
unsigned capacity;
int top;
int * array;
};
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack=(struct Stack*)malloc(sizeof(struct Stack));
stack->capacity=capacity;
stack->top=-1;
stack->array=(int *)malloc(sizeof(int)*stack->capacity);
return stack;
}
int isFull(struct Stack* stack)
{ return stack->top == stack->capacity - 1; }
// Stack
int isEmpty(struct Stack* stack)
{ return stack->top == -1; }
// stack.
void push(struct Stack* stack, int item)
{
if (isFull(stack))
return;
stack->array[++stack->top] = item;
printf("%d pushed to stack\n", item);
}
// stack.
int pop(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack->array[stack->top--];
}
// stack
int peek(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack->array[stack->top];
}
// linkedlist
void insert(struct Node** head_ref, int new_data)
{
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp)
{
push(stack,temp->data);
temp=temp->next;
}
while(curr)
{
if(pop(stack)==curr->data)
{
curr=curr->next;
}
else
exit(0);
}
return true;
}
// Driver program to test above functions
int main()
{
struct Stack* stack = createStack(100);
struct Node* head=NULL;
insert(&head,1);
insert(&head,2);
insert(&head,1);
printf("%s",compare(stack,head));
return 0;
}
Function compare has at least two errors. The first one is that it uses uninitialized pointer temp
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp) // <= temp is not initialized
{
The second one is that the function never returns false though according to the assignment it has to return false if values in the list and in the stack do not match.
Instead of returning false you call function exit
else
exit(0);
I would write the function the following way
bool compare(struct Stack *stack, struct Node *head )
{
struct Node *current = head;
for ( ; current != NULL && !isFull( stack ); current = current->next )
{
push( stack, current->data );
}
current = head;
while ( current != NULL && !isEmpty( stack ) && pop( stack ) == current->data )
{
current = current->next;
}
return current == NULL && isEmpty( stack );
}
It is the only correct function implementation among presented here function implementations in other answers.:)
As C does not have type bool then that you could use name bool in a program written in C you have to include header <stdbool.h> or define this name yourself as a typedef either of _Bool (if your compiler supports this type) or of int.
You could declare the return type of the function as int if you do not want to include header <stdbool.h>. For example
int compare(struct Stack *stack, struct Node *head );
Take into account that you need to write also functions that will free all allocated memory for the list and the stack.
For example you could free memory allocated for the stack the following way
void freeStack( struct Stack **stack )
{
if ( *stack != NULL ) free( ( *stack )->array );
free( *stack );
*stack = NULL;
}
The same way you could free the memory allocated for the list
void freeList( struct Node **head )
{
if ( *head != NULL )
{
Node *current = ( *head )->next;
while ( current != NULL )
{
Node *temp = current;
current = current->next;
free( temp );
}
}
free( *head );
*head = NULL;
}
struct Node* temp;
temp is not initialized in
bool compare(struct Stack* stack,struct Node* head)
struct Node* temp,* curr=head;
is not
struct struct Node* temp=head,* curr=head;
Using uninitialized variables lead to undefined behavior.
You've got an uninitialized local variable temp:
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp) // NOT INITIALIZED
{
push(stack,temp->data);
temp=temp->next;
}
while(curr)
{
if(pop(stack)==curr->data)
{
curr=curr->next;
}
else
exit(0);
}
return true;
}
You need to fix that first; I think the following should work:
bool compare(struct Stack* stack,struct Node* head)
{
struct Node *curr;
for (curr = head; curr != NULL; curr = curr->next)
{
push(stack, curr->data);
}
for (curr = head; curr != NULL; curr = curr->next)
{
if (pop(stack) != curr->data)
return false;
}
return true;
}
Next, you're printing a boolean result with "%s", which is for strings. You need to do something like:
c=compare(stack,head);
printf("%d\n", c);
or alternatively
printf("%s\n", c ? "true" : "false");
At this point, it no longer crashes for me, and works for a couple simple test cases. You might think about how to handle the case of overflowing the stack, and also consider formatting your code to make it more readable.
bool compare(struct Stack* stack,struct Node* head) {
struct Node* temp=head;//<- Needs initialising. It wasn't.
struct Node* curr=head;
while(temp) {
push(stack,temp->data);
temp=temp->next;
}
while(curr) {
if(pop(stack)==curr->data) {
curr=curr->next;
} else {
//exit(0); <--Some mistake surely!
return false; //Slightly less drastic!
}
}
return true;
}
It's slightly a matter of taste but I find long series of variable declarations to be difficult to read and hence error-prone.
You only really need one local variable - but your compiler probably optimizes that away.
exit(0) will abruptly end the program. Most likely indicates 'success' (the exit of 0).
You should return false;.
PS: Credit for using #include <stdbool.h>.

Why are all elements replaced in stack after new one added?

Simple stack implementation in C:
struct Stack {
char* data;
Stack* prev;
};
void push(char* data, Stack** stack) {
Stack* node = (Stack*)malloc(sizeof(Stack));
node->data = data;
node->prev = *stack;
*stack = node;
}
int main() {
Stack* top = NULL;
push("1", &top);
push("2", &top);
push("3", &top);
}
then top->prev->prev->data results into 3 same as top->prev->data and top->data.
Can anybody explain why?
So, it appears to work correctly.
#include <stdlib.h>
#include <stdio.h>
struct Stack {
char* data;
struct Stack* prev;
};
void push(char *data, struct Stack** stack) {
struct Stack* node = malloc(sizeof(struct Stack));
node->data = data;
node->prev = *stack;
*stack = node;
}
int main() {
struct Stack* top = NULL;
push("1", &top);
push("2", &top);
push("3", &top);
printf("top->data: %s\n", top->data);
printf("top->prev->data: %s\n", top->prev->data);
printf("top->prev->prev->data: %s\n", top->prev->prev->data);
}
The output is:
top->data: 3
top->prev->data: 2
top->prev->prev->data: 1

Queue popping out some garbage value

If i enter 2 as input, the output is -572662307.
Can anyone figure out the problem?
struct node
{
int rollno;
struct node*n;
};
void read(struct node*);
void display(struct node*);
struct node* create();
struct node* cread();
struct node*head=NULL;
struct node*tail=NULL;
void read(struct node*p)
{
scanf("%d",&p->rollno);
p->n=NULL;
printf("\n");
}
void display(struct node*p)
{
printf("%d\n",p->rollno);
}
struct node* create()
{
struct node*q;
q=(struct node*)malloc(sizeof(struct node));
return q;
}
struct node* cread()
{
struct node*j;
j=create();
read(j);
return j;
}
void push(struct node*cur)
{
if(head==NULL)
{
head = cur;
tail = cur;
}
else
{
struct node*f;
f=head;
head->n = cur;
head=head->n;
}
}
struct node* pop()
{
struct node*p;
struct node*s = NULL;
p=tail;
if(p==NULL)
{printf("\n\t\t\tSTACK EMPTY\n");}
else
{
//display(p);
s = p;
tail=p->n;
free(p);
}
return s;
}
DWORD WINAPI workerThreadProcedure(LPVOID lparam)
{
struct node* cur;
struct node* disp = NULL;
printf("Enter the input: ");
cur =cread();
push(cur);
disp = pop();
printf("%d\n",disp->rollno);
return 0;
}
void main()
{
HANDLE workerThreadHandle[40];
int max_number=40;
for (int i = 0; i < 1; i++)
{
workerThreadHandle[i]= CreateThread( NULL,
0,
workerThreadProcedure,
(LPVOID)i,
0,
NULL
);
}
Sleep(5000);
}
I have to admit it's a bit difficult to follow but I think the problem is here:
struct node* pop()
{
struct node*p;
struct node*s = NULL;
p=tail;
if(p==NULL)
{printf("\n\t\t\tSTACK EMPTY\n");} // after that will jump to 'return' where 's' is NULL
else
{
//display(p);
s = p; // 's' and 'p' point to the same memory block now
tail=p->n;
free(p); // Ooops you've freed the memory block 's' and 'p' point to
}
return s; // You now return a freed memory block, this is undefined behavior
}
If it entered the if statement only, s will be returned NULL. In any case it's wrong.
You only free memory once you're done with it, keep track of what your pointers point to. Not sure what you wanted to do here, distinguish between the pointer and what it points to.
The pointer will expire at the end of the function, what it points to will not necessarily (especially if it's allocated with malloc).
It's entirely okay for several pointers to point to one thing and when you fiddle with that thing, it affects all pointers that point to it.

Resources