Thread: problem with linked list

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    103

    problem with linked list

    Hi

    I have created a simple linked list program but it is printing only the first element of list.

    The code is as follow:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    struct link
    {
    	int data;
    	struct link *next;
    };
    
    int main()
    {
    	struct link *head;
    	struct link *temp,*node;
    	node = NULL;
    	temp = NULL;
    	head = NULL;
    
        int ch = 1;
    	while(ch)
    	{
    		printf("\n Enter your Choice");
    		printf("\n 1: Insert");
    		printf("\n 2: Display");
    		printf("\n 3: Exit");
    		scanf("%d",&ch);
    
    		switch(ch)
    		{
    		case 1:
    
    
    			int info;
    			printf("\n Enter the number");
    			scanf("%d",&info);
    
    			
    			
                
    			 node = (link *)malloc(sizeof(link));
    			if( head == NULL )
    			{
    				node->data = info;
    				node->next = NULL;
    				head = node;
    			}
    			else
    			{
    				temp = head;
    				while( temp->next != NULL )
    					temp=temp->next;
    
                     node->data = info;  	
    				 node->next = NULL;
          			 temp = node;
    				
    				  
        		}
    			break;
    
    		case 2:
              
    			 temp = head;
    			 while ( temp !=NULL ){
    				 printf("\n %d",temp->data);
    				 temp = temp->next;
    			 }
    			 break;
    
    		case 3:
    			exit(0);
    			break;
    		}
    	}
    }
    Can any body tell me where is the problem?

    Thanks

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    It's in your insert:
    Code:
    			else
    			{
    				temp = head;
    				while( temp->next != NULL )
    					temp=temp->next;
    
                     node->data = info;  	
    				 node->next = NULL;
          			 temp = node;
    But temp is not attached to anything! It's just a variable name you are assigning to. You need to attach to a next pointer somewhere. To do that, you need to keep a "previous" pointer:
    Code:
    			else
    			{
    				temp = head;
                                    previous = NULL;
    				while(temp != NULL ) {
                                            previous = temp;
    					temp=temp->next;
                                    }
                                    prev->next = node;
    See how that works?

    BTW, you should assign the data to the node first, so you have that code in one place instead of two or more (important concept!).
    Last edited by MK27; 06-09-2010 at 07:05 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    If you are comfortable with pointer,

    Code:
    struct link **href;
    node = malloc( sizeof(*node) );
    if(node==NULL ) { 
      /* handle error */
    }
    node->data = info;
    node->next = NULL;
    href = &head;
    
    while( *href != NULL ) {
       href = &(*href)->next;
    }
    *href = node;

  4. #4
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    Thanks for the reply......

    I have one more question....as If I have to add more nodes at end , then every time while loop will run.

    Is there any other way by which I can avoid this looping.

    I tried with some temp pointers variable but doesn't work.

    Thanks

  5. #5
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    You can have tail pointer to keep track of the end of list.

    Code:
    head = tail = NULL;
    /* code */
    /* insert */
    if( head == NULL ) {   
     head = tail = node;
    } else {
      tail->next = node;
      tail = node;
     }

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by nickman View Post
    I have one more question....as If I have to add more nodes at end , then every time while loop will run.

    Is there any other way by which I can avoid this looping.
    Add to the beginning and not the end. This is easier and faster, and always the same:
    Code:
    temp = head;
    head = node;
    node->next = temp;
    Even if head is currently NULL (ie, this is first node added) that's fine.

    However, it is obviously not a good idea if the list is time ordered.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    Hi

    I have created the the same program using functions,but this time it is not working.
    Pointer head has null value.
    I can understand that this is due to scoping problem,since head and other pointers are declared inside main and I am passing them as variable to functions.( Please correct me if I am wrong)

    The alternate sol. can be that I declare head and other variable as global; but that will be a bad practice.

    Can anybody help me to know how to do it?

    The code I have wrote is:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    struct link
    {
    	int data;
    	struct link *next;
    };
    
    void insert(static struct link *head)
    {
    			struct link *temp,*node;
                int info =0;
    			printf("\n Enter the number");
    			scanf("%d",&info);
                
    			 node = (link *)malloc(sizeof(link));
    			if( head == NULL )
    			{
    				node->data = info;
    				node->next = NULL;
    				head = node;
    			}
    			else
    			{
    				temp = head;
    				while( temp->next != NULL )
    					temp=temp->next;
    
                     node->data = info;  	
    				 node->next = NULL;
    				 temp->next = node;
    			}
    }
    
    void display(static struct link *head)
    {
    	struct link *temp;
    	temp = head;
    
    	while ( temp !=NULL ){
    	 printf("\n %d",temp->data);
    	 temp = temp->next;
    	}
    }
    
    int main()
    {
    	struct link *head;
    	struct link *temp,*node;
    	node = NULL;
    	temp = NULL;
    	head = NULL;
    
        int ch = 1;
    	while(ch)
    	{
    		printf("\n Enter your Choice");
    		printf("\n 1: Insert");
    		printf("\n 2: Display");
    		printf("\n 3: Exit");
    		scanf("%d",&ch);
    
    		switch(ch)
    		{
    		case 1:
                 insert(head);
                 break;
    
    		case 2:
                 display(head);
    			 
    			 break;
    
    		case 3:
    			exit(0);
    			break;
    		}
    	}
    }
    Thanks

  8. #8
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Question 4.8
    why static ?void insert(static struct link *head) ?
    Can you even compile without any error?
    which compiler? what option?

  9. #9
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    I am sorry.....

    It's not static....

    Code:
    void insert(struct link *head) {}

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by nickman View Post
    I can understand that this is due to scoping problem,since head and other pointers are declared inside main and I am passing them as variable to functions.( Please correct me if I am wrong)
    That is an issue, you are right. The reason is the same as the reason assigning to temp didn't add to the list -- because in the insert function, "head" is just the name of a variable. It is assigned a value (the parameter you pass), but if you reassign it:

    Code:
    void insert(struct link *head) {
             head = whatever;  // reassignment!
    Now head is not the same as the head of the list from main. To deal with this you need to use a pointer to the pointer:
    Code:
    void insert(struct link **head) {
             *head = whatever;  // dereference then assign
    Will work, but you have to call it with the address of head (nb, I removed the static qualifier, that is not the answer):
    Code:
    insert(&head);
    The exact same as the principle here:
    Code:
    void somefunct (int *ptr) {
             *ptr = 5;  // dereference then assign
    }
    int x;
    somefunct (&x);
    Hopefully you understand that?

    The alternate sol. can be that I declare head and other variable as global; but that will be a bad practice.
    Definitely not necessary!
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Registered User
    Join Date
    Jun 2010
    Posts
    103
    Hi

    I tried it but it's crashing.

    I have modified as follow:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    
    struct link
    {
    	int data;
    	struct link *next;
    };
    
    void insert( struct link **head)
    {
    	       
    			struct link *temp,*node;
                int info =0;
    			printf("\n Enter the number");
    			scanf("%d",&info);
                
    			 node = (link *)malloc(sizeof(link));
    			if( head == NULL )
    			{
    				node->data = info;
    				node->next = NULL;
    				*head = node;
    			}
    			else
    			{
    				temp = *head;
    				while( temp->next != NULL )
    					temp=temp->next;
    
                     node->data = info;  	
    				 node->next = NULL;
    				 temp->next = node;
    			}
    }
    
    void display( struct link **head)
    {
    	struct link *temp;
    	temp = *head;
    
    	while ( temp !=NULL ){
    	 printf("\n %d",temp->data);
    	 temp = temp->next;
    	}
    }
    
    int main()
    {
    	struct link *head;
    	struct link *temp,*node;
    	node = NULL;
    	temp = NULL;
    	head = NULL;
    
        int ch = 1;
    	while(ch)
    	{
    		printf("\n Enter your Choice");
    		printf("\n 1: Insert");
    		printf("\n 2: Display");
    		printf("\n 3: Exit");
    		scanf("%d",&ch);
    
    		switch(ch)
    		{
    		case 1:
                 insert(&head);
                 break;
    
    		case 2:
                 display(&head);
    			 
    			 break;
    
    		case 3:
    			exit(0);
    			break;
    		}
    	}
    }
    Can anybody correct it?

    Thanks

  12. #12
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    No, find yourself.

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by nickman View Post
    Can anybody correct it?
    You need to remember to dereference head appropriately, the same as if you were accessing the value in an int pointer:
    Code:
    if (*x == 5)
    if (*head == NULL)  // you still have if (head == NULL)
    This is because "head" in the function is a pointer to the pointer from main (whereas head in main is a pointer to a node):

    struct link *head is a pointer to a struct
    struct link **head is a pointer to a pointer to a struct

    Get it? The second one can be NULL on two different levels. You want the level of the *dereferenced value.
    Last edited by MK27; 06-09-2010 at 10:10 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. singly linked circular list
    By DarkDot in forum C++ Programming
    Replies: 0
    Last Post: 04-24-2007, 08:55 PM
  3. Replies: 6
    Last Post: 03-02-2005, 02:45 AM
  4. Linked list with two class types within template.
    By SilasP in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2002, 06:13 AM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM