I'm implementing a stack using two queues. I'm quite familiar with the algorithm, and have prepared the following code where the push operation is costly:
#include <stdio.h>
#include <stdlib.h>
struct queue_struct{
int ele;
struct queue_struct *next;
};
struct Queue{
struct queue_struct *front, *rear;
};
struct Stack{
struct Queue *q1, *q2;
};
void enqueue(struct Queue *q, int x){
struct queue_struct *temp=malloc(sizeof(*temp));
temp->ele=x;
temp->next=NULL;
if(q->rear!=NULL){
q->rear->next=temp;
}
q->rear=temp;
if(q->front==NULL)
q->front=temp;
//printf("The item %d has been enqueued into the queue\n", x);
}
void dequeue(struct Queue *q){
struct queue_struct *temp=q->front;
if(temp==NULL){
//printf("The queue is already empty. No more elements can be removed!\n");
return;
}
printf("The item %d has been popped from the stack\n", temp->ele);
q->front=temp->next;
if(q->rear==temp)
q->rear=NULL;
free(temp);
}
void push(struct Stack *s, int x){
enqueue(s->q2, x);
while(!(s->q1->front==NULL)){
enqueue(s->q2, s->q1->front->ele);
dequeue(s->q1);
}
struct Queue *q=s->q1;
s->q1=s->q2;
s->q2=q;
printf("The item %d has been pushed into the stack\n", x);
}
void pop(struct Stack *s){
if(s->q1->front==NULL){
printf("The stack is already empty. No more elements can be removed!\n");
return;
}
dequeue(s->q1);
}
void display(struct Stack *s){
struct queue_struct *temp=s->q1->front;
printf("The contents of the queue are:\n");
if(temp==NULL){
printf("Nothing to be shown, the queue is empty.\n");
return;
}
for(int i=0;temp!=NULL;temp=temp->next){
if(i){
printf(" ------ \n");
}
printf("| %d |\n", temp->ele);
i=1;
}
}
int main()
{
int choice, element;
struct Stack *s=malloc(sizeof(*s));
s->q1->front=s->q1->rear=NULL;
s->q2->front=s->q2->rear=NULL;
printf("LET'S START WITH AN EMPTY STACK\n\n");
while(1){
printf("MENU\n");
printf("----\n");
printf("\t1. Push an element\n");
printf("\t2. Pop an element\n");
printf("\t3. Display stack\n");
printf("\t4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch(choice){
case 1: printf("Enter the element to be pushed: ");
scanf("%d", &element);
push(s, element);
break;
case 2: pop(s);
break;
case 3: display(s);
break;
case 4: printf("Program terminated successfully!");
return 0;
default: printf("Invalid input");
}
}
}
However, I'm getting a Segmentation fault for the line(s): s->q1->front=s->q1->rear=NULL;. I'm not really sure why it is happening and how to fix it. Any help is appreciated.
You invoked undefined behavior by using values in buffer allocated via malloc() and not initialized.
You have to initialize s->q1 and s->q2 before dereferencing them.
struct Stack *s=malloc(sizeof(*s));
if (s == NULL) return 1; /* check if allocation succeeded */
s->q1 = malloc(sizeof(*s->q1)); /* allocate for s->q1 */
s->q2 = malloc(sizeof(*s->q2)); /* allocate for s->q2 */
if (s->q1 == NULL || s->q2 == NULL) return 1; /* check if allocations succeeded */
s->q1->front=s->q1->rear=NULL;
s->q2->front=s->q2->rear=NULL;
Related
I have initialised two stacks using a structure with which I am creating a queue. But the stack is not able to store the values which is why enqueue or dequeue operations are not working properly.
Here is the code:
#include<stdio.h>
#include<stdlib.h>
struct stack{
int top;
int size;
int *s;
};
int isfull(struct stack *st){
if(st->top==st->size-1){
return 1;
}
return 0;
}
int isempty(struct stack *st){
if(st->top==-1){
return 1;
}
return 0;
}
void push(struct stack *st,int x){
if(isfull(st)){
printf("FULL!!\n");
}
else{
st->top++;
st->s[st->top]=x;
}
}
int pop(struct stack *st){
int x=-1;
if(isempty(st)){
printf("EMPTY!!\n");
}
else{
x=st->s[st->top];
st->top--;
}
return x;
}
void enqueue(struct stack s1,int x){
push(&s1,x);
}
int dequeue(struct stack s1,struct stack s2){
int x=-1;
if(isempty(&s2)){
if(isempty(&s1)){
printf("QUEUE IS EMPTY!!\n");
return x;
}
else{
while(!isempty(&s1)){
push(&s2,pop(&s1));
}
}
}
return pop(&s2);
}
void display(struct stack st){
int i;
for(i=0;i<=st.top;i++){
printf("%d",st.s[i]);
}
}
int main(){
int n,choice;
struct stack s1,s2;
printf("ENTER SIZE OF QUEUE:");
scanf("%d",&n);
s1.size=n;
s2.size=n;
s1.top=-1;
s2.top=-1;
s1.s=(int *)malloc(s1.size*sizeof(int));
s2.s=(int *)malloc(s2.size*sizeof(int));
while(1){
printf("1.ENQUEUE\n");
printf("2.DEQUEUE\n");
printf("3.DISPLAY\n");
printf("4.EXIT\n");
printf("ENTER YOUR CHOICE:");
scanf("%d",&choice);
switch(choice){
case(1):
int x;
printf("ENTER DATA:");
scanf("%d",&x);
enqueue(s1,x);
break;
case(2):
int m;
m=dequeue(s1,s2);
printf("ELEMENT DELETED IS:%d\n",m);
break;
case(3):
display(s2);
break;
case(4):
exit(0);
}
}
return 0;
}
What is the error? I think there might be an issue with passing the values to the function.
The main issue is that the enqueue and dequeue don't take pointers as arguments, but struct stack. This means the function gets a copy of the given struct, and that the pointer you pass to push and pop (like &s1) is pointing to that local structure, not to the one in main. By consequence any update to the top member of that stack will not be seen by the caller.
I would suggest to:
Consistently pass pointers to struct typed arguments. This was well done for the push and pop functions, and there is no reason why it should not be done the same way for enqueue and dequeue functions.
Define a struct queue so that you abstract a bit that there are two stacks involved and don't have to pass both of them as argument to dequeue.
Create separate functions for:
creating a new stack
displaying a stack
creating a new queue
displaying a queue
checking if a queue is empty
Here is how your code would then look:
#include <stdio.h>
#include <stdlib.h>
struct stack {
int top;
int size;
int *s;
};
struct stack* newstack(int size) {
struct stack *s = malloc(sizeof(struct stack));
s->size = size;
s->s = malloc(size*sizeof(int));
s->top = -1;
return s;
}
int isfull(struct stack *st) {
return st->top == st->size - 1;
}
int isempty(struct stack *st) {
return st->top == -1;
}
void push(struct stack *st, int x) {
if (isfull(st)){
printf("Full!\n");
} else {
st->top++;
st->s[st->top] = x;
}
}
int pop(struct stack *st) {
int x = -1;
if (isempty(st)){
printf("Empty!\n");
} else {
x = st->s[st->top];
st->top--;
}
return x;
}
void displaystack(struct stack *st) {
for(int i = 0; i <= st->top; i++) {
printf("%d ", st->s[i]);
}
}
struct queue {
struct stack *s1;
struct stack *s2;
};
struct queue* newqueue(int size) {
struct queue *q = malloc(sizeof(struct queue));
q->s1 = newstack(size);
q->s2 = newstack(size);
return q;
}
int isemptyqueue(struct queue *q) {
return isempty(q->s1) && isempty(q->s2);
}
void enqueue(struct queue *q, int x) {
push(q->s1, x);
}
int dequeue(struct queue *q) {
int x = -1;
if (isemptyqueue(q)) {
printf("Queue is empty!\n");
return -1;
}
if (isempty(q->s2)) {
while (!isempty(q->s1)) {
push(q->s2, pop(q->s1));
}
}
return pop(q->s2);
}
void displayqueue(struct queue *q) {
displaystack(q->s1);
printf("| ");
displaystack(q->s2);
printf("\n");
}
int main() {
int n, choice, x, m;
printf("Enter the size of the queue: ");
scanf("%d", &n);
struct queue *q = newqueue(n);
while (choice != 4) {
printf("1. Enqueue\n");
printf("2. Dequeue\n");
printf("3. Display\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter data: ");
scanf("%d", &x);
enqueue(q, x);
break;
case 2:
m = dequeue(q);
printf("The deleted element is: %d\n", m);
break;
case 3:
displayqueue(q);
break;
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define type int
#define qsize 40
typedef struct {
int top;
type array[qsize];
}stack;
stack *initstack (){
stack *s=malloc(sizeof(stack)); s->top =0;
return s;
}
void push(stack *s,type x){
s->array[s->top++]=x;
}
type pop(stack *s){
return s->array[--s->top];
}
type isfulls(stack *s){
return s->top>=qsize;
}
type isemptys(stack *s){
return !s->top;
}
type peek(stack *s){
return s->array[s->top-1];
}
//----------------------------------------------------
typedef struct {
type head;
type tail;
int Qnoe;
type elements[qsize];
}queue;
queue *initqueue(){
queue *s=malloc(sizeof(queue));
s->Qnoe=0; s->head=0; s->tail=-1;
return s;
}
void enqueue(queue *s,type e){
s->elements[++s->tail%qsize]=e; s->Qnoe++;
}
type dequeue(queue *s){
type temp=s->elements[s->head++%qsize];
s->Qnoe--; return temp;
}
int isempty(queue *s){
return !s->Qnoe;
}
int isfull(queue *s){
return s->Qnoe==qsize;
}
type gethead(queue *s){
return s->elements[s->head];
}
type gettail(queue *s){
return s->elements[s->tail];
}
void display(queue *s){ ///used just to display the functions
queue *temp=initqueue();
while(!isempty(s)){
type x=dequeue(s);
printf("%d ",x);
enqueue(temp,x);
}
printf("\n\n");
while(!isempty(temp)) enqueue(s,dequeue(temp));
}
int maxvalue(queue *s){
type max,head;
queue *temp=initqueue();if(!isempty(s)) {enqueue(temp,dequeue(s)); max=gethead(s);}
while (!isempty(s)){
head=gethead(s);
if(max<head) max=head;
enqueue(temp,dequeue(s));
}
while(!isempty(temp)) enqueue(s,dequeue(temp));
return max;
}
void swap(queue *s){
type head=gethead(s),tail=gettail(s);int i=0,j=1;
queue *temp=initqueue();
while(!isempty(s)) {i++; enqueue(temp,dequeue(s));}
dequeue(temp); enqueue(s,tail); ;
while(!isempty(temp)){
if(j++==i-1) {enqueue(s,head); break;}
else {enqueue(s,dequeue(temp));}
} free(temp);
}
void insert(queue *s,type e,int index){
queue *temp=initqueue(); int i=1;
while(!isempty(s)){
if(index==i++) {enqueue(temp,e); dequeue(s);}
else enqueue(temp,dequeue(s));
}
while(!isempty(temp)) enqueue(s,dequeue(temp));
}
void revercOdd(queue *s){
queue *tempq=initqueue();
stack *temps=initstack();
while(!isempty(s)){
if(gethead(s)%2){push(temps,dequeue(s)); enqueue(tempq,1);}
else enqueue(tempq,dequeue(s));
}
while(!isempty(tempq)){
if(gethead(tempq)==1){enqueue(s,pop(temps)); dequeue(tempq);}
else enqueue(s,dequeue(tempq));
}
}
int main()
{
queue *s=initqueue();
enqueue(s,5);
enqueue(s,8);
enqueue(s,3);
enqueue(s,2);
enqueue(s,1);
enqueue(s,0);
enqueue(s,112);
printf("the queue: \n");
display(s);
printf("max value in queue : %d\n\n",maxvalue(s));
swap(s);
printf("the queue after swapping the head and tail: \n");
display(s);
printf("\nthe queue: \n");
display(s);
type e,index;
printf("enter he value of the elemnt and the index: ");
scanf("%d%d",&e,&index);
insert(s,e,index);
printf("the queue after inserting %d in the index %d: \n",e,index);
display(s);
printf("\nthe queue: \n");
display(s);
revercOdd(s);
printf("the queue after reversing odd number only: \n");
display(s);
return 0;
}
I made 4 functions 1 to get the max element in the queue 1 to get swap the head and tail of the queue 1 to take an element and index and put it in that index in the queue and 1 to reverse odd numbers only in a queue using queue and stack and a function to display the element of a given queue to check results and in the main, I check the outputs of every function work on its own, but when I use them together the last display shows the garbage element in the queue:
I am trying to implement linear queue using C but the program doesn't run even though the compiler doesn't show any error. When i try to run the program a pop up windows says "The program has stopped working". Can anyone show me what is wrong with this code and how to fix it? Any help will be appreciated.
Thank you
```
#include<stdio.h>
#define MAXSIZE 30
struct queue{
int item[MAXSIZE];
int rear;
int front;
};
typedef struct queue qu;
void enqueue(qu *q){
int data;
printf("Enter the data to be inserted(enqueued) \n");
scanf("%d", &data);
if(q->rear == MAXSIZE-1){
printf("Queue is full \n");
}
else{
q->rear++;
q->item[q->rear] = data;
}
}
void dequeue(qu *q){
if(q->rear < q->front){
printf("queue is empty \n");
}
else{
q->front++;
printf("Deleted item is \n %d \n", q->item[q->front]);
}
}
void display(qu *q){
int i;
if(q->rear < q->front){
printf("queue is empty \n");
}
else{
printf("The queue is : \n");
for( i=q->front; i<= q->rear; i++){
printf("%d \t",q->item[i]);
}
}
}
int main(){
int ch;
qu *q;
q->front = 0;
q->rear = -1;
printf("MENU for operation \n");
printf("1: Enqueue \n 2: Dequeue \n 3: Display \n 4: Exit \n");
do{
printf("Choose an operation \n");
scanf("%d", &ch);
switch(ch){
case 1:
enqueue(q);
break;
case 2:
dequeue(q);
break;
case 3:
display(q);
break;
case 4:
break;
default:
printf("Choose number from 1-4");
}
}
while(ch != 4);
return 0;
}
With qu *q; you define a pointer with indeterminate value to a qu object; this is of no use. Instead you've to define qu q; and write q. everywhere you wrote q-> and (&q) everywhere you wrote (q), respectively, in main.
Then in dequeue with
q->front++;
printf("Deleted item is \n %d \n", q->item[q->front]);
you erroneously increment front before taking the front item from the queue; correct:
printf("Deleted item is \n %d \n", q->item[q->front++]);
Finally note that your queue implementation could be improved by reusing released queue positions.
I'm trying to implement priority. A higher value of variable prior implies a lower priority in my code. Here it is:
#include <stdio.h>
#include <stdlib.h>
struct MinMax_PriorityQueue{
int ele, prior;
struct MinMax_PriorityQueue *next;
};
int isEmpty(struct MinMax_PriorityQueue **pq){
return ((*pq)==NULL);
}
int checkPriority(int p){
return(p>0);
}
void enqueue(struct MinMax_PriorityQueue **pq, int x, int p){
struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
//struct MinMax_PriorityQueue *temp1=*pq;
if(!checkPriority(p)){
printf("Priority should be greater than 0");
return;
}
temp->ele=x;
temp->prior=p;
temp->next=NULL;
/*if(isEmpty(pq)){
*pq=temp;
}
while(temp1->next!=NULL){
temp1=temp1->next;
}*/
(*pq)->next=temp;
printf("The item %d with priority %d has been enqueued into the priority queue\n", x, p);
}
int maxPriority(struct MinMax_PriorityQueue **pq){
struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
temp=*pq;
int maxp=temp->prior;
while(temp!=NULL){
if(temp->prior<=maxp)
maxp=temp->prior;
temp=temp->next;
}
return maxp;
}
void dequeue(struct MinMax_PriorityQueue **pq){
if(isEmpty(pq)){
printf("The priority queue is empty. No more elements can be removed!\n");
}
int maxp=maxPriority(pq);
struct MinMax_PriorityQueue *temp=*pq;
while(temp!=NULL){
if(temp->prior==maxp){
printf("The item %d with priority %d has been dequeued from the priority queue\n", temp->ele, temp->prior);
free(temp);
break;
}
temp=temp->next;
}
}
void minSearch(struct MinMax_PriorityQueue **pq){
struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
temp=*pq;
int minp=0;
while(temp!=NULL){
if(temp->prior>=minp)
minp=temp->prior;
temp=temp->next;
}
temp=*pq;
while(temp!=NULL){
if(temp->prior==minp){
printf("The element %d has minimum priority\n", temp->ele);
}
temp=temp->next;
}
}
void maxSearch(struct MinMax_PriorityQueue **pq){
int maxp=maxPriority(pq);
struct MinMax_PriorityQueue *temp=*pq;
while(temp!=NULL){
if(temp->prior==maxp){
printf("The element %d has maximum priority\n", temp->ele);
}
temp=temp->next;
}
}
void display(struct MinMax_PriorityQueue *pq){
struct MinMax_PriorityQueue *temp=pq;
printf("The contents of the priority queue are:\n");
if(isEmpty(&temp)){
printf("Nothing to be shown, the priority queue is empty.\n");
return;
}
for(int i=0;temp!=NULL;temp=temp->next){
if(i){
printf(" ------ \n");
}
printf("| %d |\n", temp->ele);
i=1;
}
}
int main()
{
int choice, element, priority;
printf("LET'S START WITH AN EMPTY QUEUE\n\n");
struct MinMax_PriorityQueue *pq=malloc(sizeof(*pq));
pq=NULL;
while(1){
printf("\nMENU\n");
printf("----\n");
printf("\t1. Enqueue\n");
printf("\t2. Dequeue\n");
printf("\t3. Display queue\n");
printf("\t4. Search minimum priority\n");
printf("\t5. Search maximum priority\n");
printf("\t6. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch(choice){
case 1: printf("Enter the element to be enqueued: ");
scanf("%d", &element);
printf("Enter its priority: ");
scanf("%d", &priority);
enqueue(&pq, element, priority);
break;
case 2: dequeue(&pq);
break;
case 3: display(pq);
break;
case 4: minSearch(&pq);
break;
case 5: maxSearch(&pq);
break;
case 6: printf("Program terminated successfully!\n");
return 0;
default: printf("Invalid input");
}
}
}
Upon enqueuing, I find a segmentation fault in the line: (*pq)->next
in the enqueue() function. I can't wrap my head around why that is happening. Is it because I took an argument of type struct MinMax_PriorityQueue **?
Any help is appreciated.
(*pq)->next=temp; in the enqueue function causes segfault as *pq is NULL on the first call.
You shouldn't have commented out the check for NULL. You need it.. but like
if(isEmpty(pq)){
*pq=temp;
return; // Add this
}
BTW:
The reason the *pq is NULL on the first call of enqueue is this code in main
struct MinMax_PriorityQueue *pq=malloc(sizeof(*pq));
pq=NULL; // You set pq back to NULL (and leaks memory)
But you shouldn't do the malloc in main to start with. Simply do:
struct MinMax_PriorityQueue *pq=NULL; // Empty queue
I was trying to make a simple Linked List program, also when I'm trying to pop the first element from the list , it's not popping and it still remains the first element in the list, please help me resolve this error.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
void create(stack *s){
if(s == NULL){
s = (stack*)malloc(sizeof(stack)*1);
(s->next)=NULL;
}
else{
stack *temp = (stack*)malloc(sizeof(stack)*1);
(temp->next)=s;
s=temp;
}
}
void push(stack *s, char x){
create(s);
(s->value)=x;
}
void isEmpty(stack *s){
if(s == NULL){
printf("List is Empty!\n");
}
else{
printf("List is not Empty!\n");
}
}
char pop(stack *s){
if(s == NULL){
isEmpty(s);
return -1;
}
char x=s->value;
s=(s->next);
return x;
}
int main(int argc , char* argv[]){
stack *s;
create(s);
char choice,data;
printf("Stack Created\n\n");
do{
printf("Choose Option: pUsh, pOp, pEek, iseMpty, getSize, eXit: \n");
scanf(" %c",&choice);
switch(choice){
case 'U':{
printf("Enter the element to be pushed: \n");
scanf(" %c",&data);
push(s, data);
break;
}
case 'O':{
data=pop(s);
if(data != NULL){
printf("Popped: %c\n", data);
}
break;
}
}
}while(1);
return 0;
}
The line s=s->next; has no effect because s is a local varaible. You need to return the new value of s or use pointers to modify the caller's version.
I changed the argument to pop() and push() from stack * to stack **, so that we can update the stack not a local variable. I removed create() as it is basically what happens during the push and I integrated it with that.
The rest is straightforward and I also added the free() call in pop(). Take a look:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack{
int value;
struct stack *next;
}stack;
void push(stack **s, int x){
stack *temp = (stack*)malloc(sizeof(stack)*1);
temp->value = x;
temp->next = NULL;
if(*s == NULL){
*s = temp;
}else{
temp->next = *s;
*s=temp;
}
}
char pop(stack **s){
if(*s == NULL){
return -1;
}
char x=(*s)->value;
stack *tmp = *s;
*s=(*s)->next;
free(tmp);
return x;
}
int main(int argc , char* argv[]){
stack *s;
char choice,data;
printf("Stack Created\n\n");
do{
printf("Choose Option: pUsh, pOp, pEek, iseMpty, getSize, eXit: \n");
scanf(" %c",&choice);
switch(choice){
case 'U':{
printf("Enter the element to be pushed: \n");
scanf(" %c",&data);
push(&s, data);
break;
}
case 'O':{
data=pop(&s);
if(data != -1){
printf("Popped: %c\n", data);
} else {
printf("Stack is empty. nothing popped");
}
break;
}
}
}while(1);
return 0;
}
Here you have to use pointer to pointer if u want to pass pointer as an argument
char pop(stack **s)
{
**s=s->next;
}
this is a temporary solution u should also consider deleting the memory you allocated using the malloc function or else it will lead to memory leak
also pass the address of the pointer s while you call it in the pop function