The given program is not showing all the elements of the linked list.
I am having problem in identifying the error.
At first I initialized the head with a null value then made a temporary variable and assigned it an integer value and pointer to the next node.
Then I made an another node named temp1 and linked it with the head.
It will only be linked when "i" will be equal to 1.
Then equated temp1 to the next node and did the same.
//Linked list
//Inserting the nodes.
#include <stdio.h>
struct node
{
int n;
struct node *next;
};
struct node *head;
int main ()
{
int i, s, x, y;
i = 0;
struct node *temp;
struct node *temp1;
struct node *cur;
head = NULL;
scanf ("%d", &s); //No. of nodes.
while (i < s)
{
scanf ("%d", &x);
if (head == NULL)
{
temp = (struct node *) malloc (sizeof (struct node));
temp->n = x;
temp->next = NULL;
head = temp;
}
else
{
temp = (struct node *) malloc (sizeof (struct node));
temp->n = x;
temp->next = NULL;
temp1 = temp;
if (i == 1)
{
head->next = temp1;
}
temp1 = temp1->next; //Assigning the next node.i.e. NULL value
}
i = i + 1;
}
cur = head;
while (cur != NULL)
{
printf ("%d", cur->n);
cur = cur->next;
}
return 0;
}
Check the following changed section
{
temp = (struct node *) malloc (sizeof (struct node));
temp->n = x;
temp->next = NULL;
head = temp;
temp1 = head;
}
else
{
temp = (struct node *) malloc (sizeof (struct node));
temp->n = x;
temp->next = NULL;
temp1->next = temp;
temp1 = temp1->next; //Assigning the next node.i.e. NULL value
}
Instead of relying on
if (i == 1) {
head->next = temp1;
}
I assign head on temp1 while creating the head, which is meant to be happen only first time.
There were also some linkage issues in your else portion.
You lose nodes beyond the first two, since you never link them to the list. Use meaningful names for variables: rename temp1 to tail and initialize it to NULL in the beginning. Then the loop body becomes:
if (scanf(" %d", &x) != 1) {
// FIXME: handle error
}
temp = malloc(sizeof(*temp));
temp->n = x;
temp->next = NULL;
if (tail == NULL) {
head = temp;
} else {
tail->next = temp;
}
tail = temp;
++i;
(Untested.)
Rationale: You want to add new nodes to the end (tail) of the list. The easiest way is to keep track of the tail in an appropriately-named variable, and simply link every node to tail->next instead of convoluted logic like checking for the node count, etc. The only special case is the empty list, i.e., both head and tail are NULL, and the difference is just one line, so don't duplicate the whole block of code to set up the new node.
For starters you have to include the header <stdlib.h>.
The problem is in this statement
temp1 = temp;
if i is not equal to 1 then after this statement
temp1 = temp1->next;
temp1 becomes equal to NULL.
So all other nodes are not added to the list because there is a cycling
temp1 = temp;
//...
temp1 = temp1->next;
Change the loop the following way
while (i < s)
{
scanf ("%d", &x);
if (head == NULL)
{
temp = (struct node *) malloc (sizeof (struct node));
temp->n = x;
temp->next = NULL;
head = temp;
temp1 = head;
}
else
{
temp = (struct node *) malloc (sizeof (struct node));
temp->n = x;
temp->next = NULL;
temp1->next = temp;
temp1 = temp;
}
i++;
}
Pay attention to that you should declare variables in a block scope where they are used. Otherwise the program will be unreadable.
The approach you are using can be called as an Java approach.
In C the program can look much simpler. For example
#include <stdio.h>
#include <stdlib.h>
struct node
{
int n;
struct node *next;
};
struct node *head;
int main( void )
{
struct node **temp = &head;
size_t n = 0;
scanf( "%zu", &n );
for ( size_t i = 0; i < n; i++ )
{
*temp = (struct node *) malloc ( sizeof ( struct node ) );
int value = 0;
scanf ( "%d", &value);
( *temp )->n = value;
( *temp )->next = NULL;
temp = &( *temp )->next;
}
for ( struct node *cur = head; cur != NULL; cur = cur->next )
{
printf ("%d -> ", cur->n );
}
puts( "NULL" );
return 0;
}
Its output might look like
1 -> 2 -> 3 -> NULL
Related
After I compile the code, there is no output at all.
Why is the value 10 not inserted at the end of the linked list?
I thought that after p == NULL, the while loop is exited, j->next would be NULL as well. So, the temp node will be inserted at the end of the linked list.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
}*first=NULL;
void Create(int array[], int size)
{
int i;
struct Node *temp, *last;
first = (struct Node*)malloc(sizeof(struct Node));
first->data = array[0];
first->next = NULL;
last = first;
for (i = 1 ; i < size ; i++){
temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = array[i];
temp->next = NULL;
last->next = temp;
last = temp;
}
}
void Print(struct Node *p)
{
while(p != NULL){
printf("%d ", p->data);
p = p->next;
}
}
void InsertingInSortedList(struct Node *p, int value)
{
struct Node *temp , *j = NULL;
temp = (struct Node*)malloc(sizeof(struct Node));
temp->data = value ;
temp->next = NULL;
if(p == NULL){
first = temp;
}
else
{
while(p->data < value && p){
j = p;
p = p->next;
}
temp->next = j->next;
j->next = temp;
}
}
int main (void)
{
int b[] = {1,3,5,7,8,9};
int num = 6;
Create(b,num);
InsertingInSortedList(first, 10);
Print(first);
return 0;
}
The condition p->data < value && p is wrong. You need to check if p is NULL before you dereference p.
The correct condition is p && p->data < value.
Google c short circuit evaluation for more information.
I'm trying to make a circular linked list. When I try to display the list after creating it, the program keeps on crashing. Here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node * next;
} node;
node * createList(int);
void display(node * head);
int main() {
struct node * head;
head = createList(5);
display(head);
}
node * createList(int n) {
int i = 0,data = 0;
struct node * head = NULL;
struct node * temp = NULL;
struct node * p = NULL;
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
temp->next = head;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
return head;
}
void display(node * head) {
struct node * temp = head->next;
while (temp != head) {
printf("%d-> \t",temp->data);
temp = temp->next;
}
printf("\n");
}
What am I doing wrong?
You have set every temp's next to head in temp->next = head; but did it too early (the first is just NULL). Then you tested p->next against NULL in while (p->next != NULL) { but you should have tested against head. Alternatively, you can continue to test against NULL but then you need to initialize temp->next to NULL and assign head to temp->next only after the for loop.
Your display code started from the second link.
Here is a fixed code using the first option in 1. above:
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != head) {
p = p->next;
}
p->next = temp;
}
temp->next = head;
}
Here is a fixed code using the alternative option in 1. above. You still need to initialize temp->next to NULL since malloc() does not initialize.
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
temp->next = NULL;
if (head == NULL) {
head = temp;
} else {
p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = temp;
}
}
if (temp != NULL) {
temp->next = head;
}
But in reality, there is no need to "walk" from the head on every creation. You can simply keep the previous and link it to the next:
for (i = 0; i < n; i++) {
temp = (node*)malloc(sizeof(node));
temp->data = data++;
if (head == NULL) {
head = p = temp;
} else {
p = p->next = temp;
}
}
if (temp != NULL) {
temp->next = head;
}
Here is a fix for the display():
void display(node * head) {
struct node * temp = head;
if (temp != NULL) {
do {
printf("%d-> \t",temp->data);
temp = temp->next;
} while (temp != head);
}
printf("\n");
}
The problem is on the first node you initialize:
struct node *head = NULL;
...
for (i = 0; i < n; i++) {
...
temp->next = head;
So tmp->next == NULL on the first iteration leaving head->next == NULL. That will not work for a circular list. When you attempt to insert the 2nd node:
p = head;
while (p->next != NULL) {
What was head->next again?? (oh, NULL) Dereferencing a NULL pointer (BOOM Segfault!)
Do your circular list correctly. On insertion of the first node set:
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} ...
So on the insertion of the remaining nodes you simply need:
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
Now, you handle your display() function the same way, e.g.
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}
If you make the changes, then you can test your list with:
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
Example Use/Output
$ ./bin/lls_circular_fix
0-> 1-> 2-> 3-> 4->
iterate from mid-list
2-> 3-> 4-> 0-> 1->
Lastly, you are not multiplying the type node by head in struct node * head = NULL; Write it as struct node *head = NULL; (the same for all your function declarations as well) Much more readable.
When you go to delete a note from the list, you must create a special case for both head and tail (the last node). In this sense, the singly-linked list takes a bit more effort than a doubly-linked list due to not having a prev node pointer to track the prior node.
Look things over and let me know if you have questions.
A full example would be:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
node *createList (int);
void display (node *head);
int main (void) {
struct node *head, *tmp;
head = createList(5);
display (head);
puts ("\niterate from mid-list");
tmp = head;
tmp = tmp->next;
tmp = tmp->next;
display (tmp);
}
node *createList (int n)
{
int i = 0,data = 0;
struct node *head = NULL;
struct node *temp = NULL;
struct node *p = NULL;
for (i = 0; i < n; i++) {
if (!(temp = malloc (sizeof *temp))) {
perror ("malloc-temp");
return NULL;
}
temp->data = data++;
temp->next = head; /* head is NULL on 1st node insertion */
if (head == NULL) {
head = temp;
head->next = temp; /* you must set head->next to temp */
} else {
p = head;
while (p->next != head) { /* iterate to last node */
p = p->next;
}
p->next = temp; /* now set p->next = temp */
}
}
return head;
}
void display (node *head)
{
if (!head) { /* validate list not empty */
puts ("(list-empty)");
return;
}
struct node *temp = head;
do { /* same loop problem fixed in display() */
printf ("%d-> \t", temp->data);
temp = temp->next;
} while (temp != head);
putchar ('\n');
}
For some reason, if I have a linked list that looks like 3->2->1->0, and I called deleteSecond(head), I get 3->1->0->0. Here is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int data;
struct ListNode *next;
} *LinkedList;
int deleteSecond(LinkedList list) {
if (list == NULL || list->next == NULL)
return 0;
int val = list->next->data;
LinkedList second = list->next;
list->next = list->next->next;
free(second);
return val;
}
int main() {
LinkedList head = NULL;
head = malloc(sizeof(LinkedList));
for (int i = 0; i < 4; i++) {
LinkedList newNode = malloc(sizeof(LinkedList));
newNode->data = i;
newNode->next = head;
head = newNode;
}
LinkedList ptr = head;
for (int i = 0; i < 4; i++) {
printf("%d\n", ptr->data);
ptr = ptr->next;
}
printf("\n");
deleteSecond(head);
while (head != NULL) {
printf("%d\n", head->data);
head = head->next;
}
return 0;
}
I believe my deleteSecond function should be correct. I create a pointer to my second node, and then I make the head->next = head->next->next, and the I free the pointer to the second node. I don't know why I have two 0's at the end of the list.
You are creating an empty node head which is creating problem. Your last node should point to NULL. So initializing head = NULL is the correct one.
LinkedList head = NULL;
// head = malloc(sizeof(LinkedList));
for (int i = 0; i < 4; i++) {
LinkedList newNode = malloc(sizeof(LinkedList));
newNode->data = i;
newNode->next = head;
head = newNode;
}
head = malloc(sizeof(LinkedList));
This is wrong. Correct would be
head = malloc(sizeof(*head));
Then again same way it would be
LinkedList newNode = malloc(sizeof(*newNode));
Now let's see what you did here.
head's data or link attribute is never initialized. So you get undefined behavior accessing it.
This is the code you wanted to write if you want to allocate memory to head.
...
int main(void) {
LinkedList head = NULL;
head = malloc(sizeof(*head));
if( head == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
head->next = NULL;
head->data = 2017; // dummy data.
for (int i = 0; i < 4; i++) {
LinkedList newNode = malloc(sizeof(*newNode));
if( newNode == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
newNode->data = i;
newNode->next = head;
head = newNode;
}
...
...
deleteSecond(head);
while (head != NULL) {
printf("%d\n", head->data); // prints 2017 also. But deletes the node that was in second position.
head = head->next;
}
return 0;
}
Here we have used one extra node for holding the dummy data. Yes! it's not needed. This dummy node is doing nothing significant other than providing an next link for the newNodes which is not needed if you just use head as LinkedList or struct LinkedNode* and allocates no memory to it. It suggests we can eliminate than and simply use the pointer to struct ListNode namely head.
Then the code will be simply like
LinkedList head = NULL;
for (int i = 0; i < 4; i++) {
LinkedList newNode = malloc(sizeof(*newNode));
if( newNode == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
newNode->data = i;
newNode->next = head;
head = newNode;
}
There are couple of things you can consider
Don't hide pointers under typedef.
Do check the return value of malloc.
Do free the memory that you allocate after you are done working with it.
The code can be written this way also. It doesn't use the pointer under typedef and modularize the reusable codes.
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int data;
struct ListNode *next;
} ListNode;
void freeMemList(ListNode *head){
ListNode *temp;
while(head!=NULL){
temp = head;
head = head->next;
free(temp);
}
}
int deleteSecond(ListNode * list) {
if (list == NULL || list->next == NULL)
return 0;
int val = list->next->data;
ListNode * second = list->next;
list->next = list->next->next;
free(second);
return val;
}
void printList(ListNode *head){
while (head != NULL) {
printf("%d\n", head->data);
head = head->next;
}
}
struct ListNode * addNodes(struct ListNode* head, int n){
for (size_t i = 0; i < n; i++) {
ListNode * newNode = malloc(sizeof(*newNode));
if( newNode == NULL){
fprintf(stderr, "%s\n","Error in malloc" );
exit(1);
}
newNode->data = i;
newNode->next = head;
head = newNode;
}
return head;
}
int main(void) {
ListNode * head = NULL;
head = addNodes(head,4);
printList(head);
printf("********\n");
int valDeleted = deleteSecond(head);
printf("%s %d\n","Value deleted ", valDeleted );
printList(head);
freeMemList(head);
return 0;
}
I'm very new to programming and I started to learn C. Now I just cant understand why my node structure is not visible to my functions.
I try to get some help on http://www.cprogramming.com/tutorial/c/lesson7.html
but with no luck in using code blocks 13.12
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct ptr * next;
};
struct node* head;
void Insert(int x)
{
struct node *temp;
temp = (node*)malloc(sizeof(struct node));
if(head == NULL)
head = temp;
temp->data = x;
temp->data = x;
temp->next = NULL;
struct node* temp1 = head;
while(temp1-> != NULL;) {
temp1 = temp1->next;
}
temp1->next = temp;
}
void print() {
struct node* temp = head;
while(temp != NULL) {
printf("the data is %d", temp->data);
temp = temp->next;
}
}
int main ()
{
head = NULL;
int a,c;
printf("How many numbers ? : \n");
scanf("%d",&a);
for(i = 0; i<a; i++); {
printf("Enter a number:\n");
scanf("%d",&c);
Insert(c);
print();
}
}
There are quite a few lets go one by one
number 1
struct node {
int data;
struct node *next; // chagnge ptr -> node
};
number 2
struct node *temp;
temp = malloc(sizeof(struct node)); // struct node casting
number 3
while(temp1->next != NULL) { // remove semi colum and put a next
temp1 = temp1->next;
}
number 4
int i; // for while loop
for(i = 0; i<a; i++) {
Now hopefully it compiles well, check runtime errors ( if any )
and yes
return 0; // just before main
you are building an infinite loop with your first element:
temp = (struct node*)malloc(sizeof(struct node));
if(head == NULL)
head = temp;
temp->data = x;
temp->next = NULL;
struct node* temp1 = head;
while(temp1->next != NULL) { // nothing to do
temp1 = temp1->next;
}
temp1->next = temp; //temp is head and temp1 is head, so head->next points to head
you should do something like
if (head == NULL) {
//fill head and leave
} else {
//traverse to the last element and concatenate the new element
}
My program keeps on crashing. I think there's a problem in my logic. Please help! Thanks!
struct node{
int data;
struct node *prev,*next;
} *head = NULL;
void insert(){
struct node* temp = (struct node*) malloc (sizeof (struct node*));
int value;
printf("Enter an element");
scanf("%d",&value);
temp -> data = value;
temp -> next = NULL;
temp -> prev = NULL;
if(value < head -> data || head == NULL){
temp -> next = head -> next;
head = temp;
return;
}
while(head->next != NULL && value > head -> next -> data)
head = head -> next;
temp -> next = head ->next->prev;
head -> next = temp -> prev;
while (head -> prev != NULL)
head = head -> prev;
}
Try this:
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *prev,*next;
} *head = 0;
void insert(int value){
struct node* temp = (struct node*) malloc (sizeof (struct node));
//int value;
//printf("Enter an element");
//scanf("%d",&value);
temp -> data = value;
temp -> next = 0;
temp -> prev = 0;
if(head == 0) {
// no head, make temp the head
head = temp;
} else if(value > head->data) {
// put temp in front of the head
temp->next = head;
head->prev = temp;
head = temp;
} else {
// put temp after the head
struct node *this = head;
struct node *prev = 0;
while(this && this->data > value) {
prev = this;
this = this->next;
}
temp->next = this;
temp->prev = prev;
prev->next = temp;
if(this) {
this->prev = temp;
}
}
}
int main() {
insert(1);
insert(3);
insert(4);
struct node *t = 0;
for(t = head; t; t = t->next) {
printf("%d\n", t->data);
}
}
This one compiles and sorts in descending value. Note I commented out your scanf
and made insert take a parameter.
the space you malloc is not enough.
change
struct node* temp = (struct node*) malloc (sizeof (struct node*));
to
struct node* temp = (struct node*) malloc (sizeof (struct node));
As a start, think about these two lines and what happens if head == NULL:
if(value < head->data || head == NULL){
temp->next = head->next;
Specifically what is head->next?
There are two core problems I see.
You are not allocating sufficient space for a node struct. sizeof(struct node *) returns the size of a node pointer, not a node. This:
struct node* temp = (struct node*) malloc (sizeof (struct node*));`
... should be this:
struct node* temp = (struct node*) malloc (sizeof (struct node));
Be careful with pointers:
if (value < head -> data || head == NULL)
... what is the value of head->data if you haven't initialized head? (e.g. it is still NULL). Your program will fetch data from address NULL with an offset for field data. Address NULL is not valid / is part of protected memory space, your OS won't like this :).
You should first check if head is NULL. If it is, then you can't reference fields of head as they are invalid (in any situation). Be careful with multi-part conditional expressions to check for struct pointer NULL presence prior to subsequent parts that reference struct fields, also.