I am trying to implement stack as a linked list. Here is my current code:
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
typedef struct node {
int data;
struct node* link;
} Node;
typedef Node* list;
list head;
void push(list top, int item) {
if (head == NULL) {
head = (list) malloc(sizeof(Node));
head->data = item;
head->link = NULL;
top = head;
} else{
list temp = (list) malloc(sizeof(Node));
temp->data = item;
temp->link = top;
top = temp;
}
}
int pop(list top) {
if (top == NULL) {
printf("stack is empty");
/*int tdata=top->data;
top=top->link;
return tdata;*/
} else {
int tdata = top->data;
top = top->link;
return tdata;
}
}
void display(list top){
while (top != NULL) {
printf("%d", top->data);
top = top->link;
}
}
int main() {
int ch, item;
list top;
for (;;) {
printf("1.push\t2.pop\t3.display\t4.exit");
scanf("%d", &ch);
switch (ch) {
case 1:
printf("enter the element to be pushed");
scanf("%d",&item);
push(top,item);
break;
case 2:
item=pop(top);
printf("element popped is: %d",item);
break;
case 3:
display(top);
break;
case 4:
exit(0);
break;
default:
printf("enter valid choice");
}
}
}
When I press '2' the pop method is called, but irrespective of whatever item is on the top it prints the message "element popped is: 11". When I press '3' for the display method, I get "segmentation fault(core dumped)". Why is this happening? What modifications are needed to get this code working?
I have made several alterations to your program. The most important is to pass a pointer to the list head to functions, which itself is a pointer, so that it can be altered by the function.
I also removed the global head and initialised the local top. I have commented in the code about other matters.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *link;
} Node; // removed pointer type to Node
void push(Node **top, int item) { // takes address of the pointer
Node *temp= malloc(sizeof(Node)); // do not cast malloc
if(temp == NULL) // check that malloc did work
exit(42);
temp->data = item; // no need for separate clause at first push
temp->link = *top; // link is previous top
*top = temp; // top is new struct, pass it back
}
int pop(Node **top) { // takes address of the pointer
int tdata;
Node *temp;
if (*top == NULL) {
printf("stack is empty\n"); // added newline here and other places
return 0;
}
tdata = (*top)->data; // collect the data
temp = (*top)->link; // remember the next list item
free(*top); // give memory back
*top = temp; // pass new top back to caller
return tdata;
}
void display(Node *top){
while (top != NULL) {
printf("%d ", top->data); // added spacing
top = top->link;
}
printf("\n"); // added newline
}
int main(void) {
int ch, item;
Node *top = NULL; // initialise the list !!
do {
printf("1.push 2.pop 3.display 4.exit ");
scanf("%d", &ch);
switch (ch) {
case 1:
printf("enter the element to be pushed ");
scanf("%d",&item);
push(&top,item); // pass address so pointer can be updated
break;
case 2:
item=pop(&top); // pass address so pointer can be updated
printf("element popped is: %d\n",item);
break;
case 3:
display(top);
break;
case 4:
break;
default:
printf("enter valid choice\n");
}
} while(ch != 4); // changed the loop style
}
What is happening is that you simply do not initialize or set any value to your list pointer top.Take a good look at your insertion function push. It receives a pointer. If you want to send your member top as an [out] paramter to this function you should send a pointer to a pointer (**) or a reference to a pointer (*&). Sending top like this does not modify its value and leaves it with junk as this variable was also never initialized...
Related
So I wrote some code for a doubly-linked list and while making a function for adding a node at the end, I thought of making a pointer for the last node, but when I execute it for adding at last it crashes but adding at front end it works fine. Everything looks fine and it does not even show any error but just crashes.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *lptr;
struct node *rptr;
};
typedef struct node *Node;
Node pos(Node first, Node last)
{
Node new;
new = (Node)malloc(sizeof(struct node));
new->lptr = NULL;
new->rptr = NULL;
printf("Enter data: ");
scanf("%d", &new->data);
if (first == NULL)
{
first = new;
last = new;
}
else
{
int p;
printf("1) First\n2) Last\n");
scanf("%d", &p);
switch (p)
{
case 1:
first->lptr = new;
new->rptr = first;
first = new;
break;
case 2:
last->rptr = new;
new->lptr = last;
last = new;
break;
default:
break;
}
}
return first;
}
void dis(Node first)
{
Node p;
int c = 1;
if (first == NULL)
{
printf("Empty");
}
else
{ p=first;
while (p != NULL)
{
printf("%dst element is %d\n", c, p->data);
c++;
p = p->rptr;
}
}
}
int main()
{
int ch;
Node first, last, t;
first = NULL;
last = NULL;
for (;;)
{
printf("Insert: \n");
scanf("%d", &ch);
switch (ch)
{
case 1:
first = pos(first, last);
break;
case 2:
dis(first);
break;
default:
printf("invalid");
exit(0);
}
}
return 0;
}
Think the problem is in this part;
case 2:
last->rptr = new;
new->lptr = last;
last = new;
break;
The problem is that the function pos does not change the pointer last declared in main. It changes its local variable (parameter) last that was initialized by a copy of the value pf the pointer last declared in main. But the pointer last declared in main stays unchanged.
You should declared one more structure like for example
struct List
{
struct node *first;
struct node *last;
};
and use this structure as a parameter of the functions.
//...
int pos( struct List *list );
int main( void )
{
struct List list = { .first = NULL, .last = NULL };
pos( &list );
//...
}
Also it is much better to split the function into two functions. The first one will add a data to the beginning of the list and the second one will add a data to the tail of the list.
For example
int push_front( struct List *list, int data );
int push_back( struct List *list, int data );
I am trying to write a code on circular queue using linked list.
I stumbled to a problem where i don't exactly know if this is the correct implementation of circular queue using linked list.
Here is the code that i wrote
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
} *rear,*front,*temp,*newNode;
void create()
{
front = rear = NULL;
}
void enqueue(int data)
{
newNode = (struct node*) malloc(sizeof(struct node));
newNode -> data = data;
newNode -> next = NULL;
if(front == NULL)
front = rear = newNode;
else
{
rear -> next = newNode;
rear = newNode;
}
rear -> next = front;
}
int dequeue()
{
int x;
if (front == NULL)
{
return -1;
}
else if (front == rear)
{
x = front->data;
delete front;
front = rear = NULL;
}
else
{
node *temp = front;
x = temp -> data;
front = front -> next;
rear -> next = front;
delete temp;
}
return x;
}
int empty()
{
if(front == NULL)
{
return 1;
}
else
return 0;
}
void display()
{
node *temp = front;
printf("\nCIRCULAR QUEUE : ");
do
{
printf("%d ",temp->data);
temp = temp->next;
}while (temp != front);
}
int main()
{
int num,choice;
while(1)
{
printf("\n\nQUEUE OPERATIONS\n\n1.ENQUEUE\n2.DEQUEUE\n3.DISPLAY\n\n");
scanf("%d",&choice);
switch (choice)
{
case 1:
printf("\nEnter item : ");
scanf("%d",&num);
enqueue(num);
break;
case 2:
if(!(empty()))
printf("\nDequeued element : %d",dequeue());
else
printf("\nEMPTY QUEUE\n");
break;
case 3:
display();
break;
default: exit(0);
}}
return 0;
}
When i enqueue integers to the program it seems to run the queue program just fine. Then i dequeued 2 numbers and the first 2 numbers was deleted. Then i inserted 2 more numbers, but when i displayed the numbers, the recently inserted numbers got displayed in the back, not at the front.
Is there a solution? or is this just the correct implementation of circular queue using linked list?
This implementation is wrong.
Firstly, in the function dequeue(), you used delete front; and delete temp;.
This is an invaild syntax in C. Also, even if this code were C++, this is bad because the buffer is allocated via malloc(). You will have to use free(front); and free(temp); instead.
Secondly, you didn't check if the queue is empty in the display() function. Also the call of display() is not guarded with empty() check unlike it is done for dequeue() function. NULL will be dereferenced and Segmentation Fault may happen when display() is called when the queue is empty.
Also note that you should check the return values of scanf() to check if it actually read data (or didn't read, reaching at EOF or invalid input) and casting result of malloc() is discouraged.
I'm trying to create a program which creates and display linked list.
Now i'm having trouble with my create_list() function, it doesn't create any list.
What i'm doing wrong ?
Sorry for bad english :/
CODE :
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
int main(){
node *start;
start = NULL;
int a,n,on = 1;
while(on == 1){
printf(" \n choose: \n 1 --- create list \n 2 --- display list \n");
scanf("%d",&n);
switch(n){
case 1:
printf("-------------------------------------------- \n");
printf(" Enter the elements. The last element is 0 \n");
printf("-------------------------------------------- \n");
Create_list();
Display_list(start);
break;
case 2:
Display_list(start);
break;
}
}
system("pause");
return 0;
}
void Display_list(node *curr){
if(curr){
while (curr->next != NULL){
printf("%d \n",curr->data);
curr=curr->next;
}
} else {
printf(" \n The list is not created ! \n");
}
}
void Create_list(node *curr){
int i;
node *start = NULL;
if (start == NULL){
curr = (node *)malloc(sizeof(node));
start=curr;
while ( i != 0){
scanf("%d",&i);
if(i == 0){
curr->next=NULL;
curr=start;
} else {
curr->data=i;
curr->next=(node *)malloc(sizeof(node));
curr=curr->next;
}
}
} else {
printf(" \n list already exists ! \n");
}
}
The function Create_List(node *curr) needs some arguments. You are not passing any arguments from main(). Did your code compile?
The function Create_List(node *curr) needs some arguments. You are not passing any arguments from main(). Did your code compile?
What you should do is take a node in main which will store location of first node of the linked list.
void Insert(struct node **q, int num) //Num is the data to be added and **q is the pointer to the first node of the list.
{
struct node *temp, *r;
temp = *q;
if (*q == NULL) {
temp = ((struct node *)malloc(sizeof(struct node)));
temp->data = num;
temp->link = NULL;
*q = temp;
}
else {
while (temp->link != NULL)
temp = temp->link;
r = ((struct node *)malloc(sizeof(struct node)));
r->data = num;
r->link = NULL;
temp->link = r;
}
}
The start in Create_list is not related to the start in main. Since both are local to their respective functions, one can't even see the other. So setting start doesn't actually set start, if you will. :P
You'll need to either bring start outside of the functions and make it global, or pass &start (as a node**) from main into Create_list and modify *start to set the list head. (The latter is generally preferable, as globals are often trouble waiting to happen.)
There are huge amounts of error, Seriously what's wrong ?
I tried using it wihout typedef but what's the problem? can anyone help me debug this please?
struct node {
int info;
struct node *link;
};
int main (void)
{
int choice;
struct node *top;
top = NULL;
while (1) {
printf("1.Push\n");
printf("2.Pop\n");
printf("3.Display\n");
printf("4.Quit\n");
printf("Enter your choice : ");
scanf("%d", &choice);
switch(choice) {
case 1:
push();
break;
case 2:
pop();
break;
case 3:
display();
break;
case 4:
exit(1);
default:
printf("Wrong choice\n");
}
}
return 0;
}
void push (void)
{
struct node *tmp;
int pushed_item;
tmp = malloc(sizeof(struct node));
printf("Input the new value to be pushed on the stack : ");
scanf("%d", &pushed_item);
tmp->info = pushed_item;
tmp->link = top;
top = tmp;
}
void pop (void)
{
struct node *tmp;
if (top == NULL)
printf("Stack is empty\n");
else {
tmp = top;
printf("Popped item is %d\n", tmp->info);
top = top->link;
free(tmp);
}
}
void display (void)
{
struct node *ptr;
ptr = top;
if (top == NULL)
printf("Stack is empty\n");
else {
printf("Stack elements :\n");
while (ptr != NULL) {
printf("%d\n", ptr->info);
ptr = ptr->link;
}
}
}
First off, the main function is going to have to be below the functions it calls. Secondly, you need to #import <stdio.h> to use printf. Thirdly, top is not a global variable so you can't just use it inside the display function.
Work from there.
Try putting this snippet at the top of your file:
#include <stdio.h>
#include <stdlib.h>
void push(void);
void pop(void);
void display(void);
struct node* top; // good catch by Borealid
I wrote a program that inserts nodes into a linked list in descending order.But whenever I test my code with numbers 12,14,13,19,7 in this order.Whenever I entered 7 I took 7 is already in the list.But as easily seen 7 is not in the list before I inserted.After give this error,if I choose print option by typing 2 my program entered in an infinite loop.I can not see my mistake and I am very confused.
#include <stdio.h>
#include <stdlib.h>
struct node {
int content;
struct node* nextLink;
};
typedef struct node NODE;
void print (NODE*);
int insertNode (NODE** head, int x);
int main (void)
{
int num, choice;
NODE* head;
head = NULL;
do {
printf("\nPlease press 1 to insert or press 2 to print or press 0 to exit\n");
scanf("%d", &choice);
switch (choice) {
case 0:
return 0;
break;
case 1:
printf("Enter an integer to insert into the linkedlist: ");
printf("\n");
scanf("%d", &num);
insertNode(&head, num);
break;
case 2:
print(head);
break;
default:
printf("You entered an invalid number\n");
return 0;
break;
}
} while (choice == 1 || choice == 2);
return 0;
}
int insertNode (NODE** head, int i)
{
NODE* newNode;
newNode = (NODE*)malloc(sizeof(NODE));
newNode->content = i;
NODE* temporary = *head;
newNode->nextLink = NULL;
if ((*head == NULL) || ((*head)->content) < i) {
*head = newNode;
(*head)->nextLink = temporary;
}
else {
do {
if (((temporary->content) > i) && ((temporary->nextLink->content) < i)) {
newNode->nextLink = temporary->nextLink;
temporary->nextLink = newNode;
return;
}
else if (temporary->content == i) {
printf("To be inserted value is already in the list\n");
return;
}
temporary = temporary->nextLink;
} while (temporary->nextLink != NULL);
if (temporary->content == i) {
printf("To be inserted value is already in the list\n");
return;
}
temporary->nextLink = newNode;
}
return 0;
}
void print (NODE* head)
{
if (head == NULL) {
printf("\nLinkedList is empty \n");
}
while (head != NULL) {
printf("%d ", head->content);
head = head->nextLink;
}
}
I compiled it and ran it and it seemed to work fine except for one thing. insertNode is defined to return an int, yet 3 of the return statements are void returns. To get it to compile, I changed them to return 0;. If you were able to compile and run it as is, then it could be the stack was getting destroyed by the inconsistent returns.
Your code won't work, if the first two values to be inserted are in descending order. It would give segmentation fault.
For the insertion of 2nd element you need to be careful
So after if condition
else if (temporary->content > i && temporary->nextLink==NULL)
(*head)->nextLink = newNode;
Your code is doing too much. If you code it differently, there are no special cases (such as insert at the top, insert at the tail of the list).
int insertNode (NODE **head, int val)
{
NODE *newnode;
for ( ; *head; head = &(*head)->nextLink) {
if ( (*head)->content == val) {
printf("To be inserted value (%d)is already in the list\n", val);
return 0;
}
if ( (*head)->content > val) break;
}
newnode = malloc(sizeof *newnode); // Maybe check return here ;-)
newnode->content = val;
newnode->nextLink = *head;
*head = newnode;
return 1;
}