Lakshit Chawla
Lakshit Chawla

Reputation: 13

insertion in a singly linked list at a specific position

I was just going through singly linked list.. and I copied this piece of code from reference book.. but I don't know how to run it in main.. what should I pass as an argument in struct node *new? I have no idea.. please help if possible....

struct node *insertatspecificposition(  struct node *new,int n){
    struct node *pred = head;
    if(n<=1){
        new->next = head;
        return new;
    }
    while(--n && pred != NULL ){
        pred = pred->next;
    }
    if(pred == NULL){
        return NULL;
    }
    new->next = pred->next;
    pred->next = new;
    return head;
}

Upvotes: 1

Views: 911

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 311078

The presented function has a logical error.

When the position is set equal to 1 then the function inserts a new node before the current head node due to this code snippet

if(n<=1){
    new->next = head;
    return new;
}

So for example if you have an empty list (head is equal to NULL) then calling the function like

head = insertatspecificposition( a_new_node_with_value_1, 1 );

you will get the list that looks like

1 -> null

Now it is logical consistent that if for a next call of the function you will specify the position 2 you will get the list that looks like

1 -> 2 -> null

However such a call

head = insertatspecificposition( one_more_new_node_with_value_2, 2 );

returns NULL instead of returning the current value of the pointer head.

Here is a demonstrative program.

#include <stdio.h>
#include <stdlib.h>

struct node
{
    int data;
    struct node *next;
} *head;

struct node * create( int data )
{
    struct node *new = malloc( sizeof( struct node ) );
    
    if ( new != NULL )
    {
        new->data = data;
        new->next = NULL;
    }
    
    return new;
}

struct node *insertatspecificposition(  struct node *new,int n){
    struct node *pred = head;
    if(n<=1){
        new->next = head;
        return new;
    }
    while(--n && pred != NULL ){
        pred = pred->next;
    }
    if(pred == NULL){
        return NULL;
    }
    new->next = pred->next;
    pred->next = new;
    return head;
}

void display( void )
{
    for ( struct node *current = head; current != NULL; current = current->next )
    {
        printf( "%d -> ", current->data );
    }
    
    puts( "null" );
}

int main(void) 
{
    display();
    
    head = insertatspecificposition( create( 1 ), 1 );
    
    display();
    
    head = insertatspecificposition( create( 2 ), 2 );
    
    display();
    
    return 0;
}

The program output is

null
1 -> null
null

instead of the expected output

null
1 -> null
1 -> 2 -> null

Pay attention also to that the function should check whether the passed pointer new is not equal to NULL.

And it is not a good design when functions depend on a global variable.

As for me then I would write the function the following way as it is shown in the demonstrative program below.

#include <stdio.h>
#include <stdlib.h>

struct node
{
    int data;
    struct node *next;
};

struct node * create( int data )
{
    struct node *new = malloc( sizeof( struct node ) );
    
    if ( new != NULL )
    {
        new->data = data;
        new->next = NULL;
    }
    
    return new;
}

int insertatspecificposition(  struct node **head, int data, size_t n )
{
    struct node *new_node = create( data );
    int success = new_node != NULL;
    
    if ( success )
    {
        while ( n-- && *head != NULL )
        {
            head = &( *head )->next;
        }
        
        new_node->next = *head;
        
        *head = new_node;
    }
    
    return success;
}

FILE * display( const struct node *head, FILE *fp )
{
    for ( ; head != NULL; head = head->next )
    {
        fprintf( fp, "%d -> ", head->data );
    }
    
    fputs( "null", fp );
    
    return fp;
}

int main(void) 
{
    struct node *head = NULL;
    
    putc( '\n', display( head, stdout ) );
    
    insertatspecificposition( &head, 1, 0 );
    
    putc( '\n', display( head, stdout ) );
    
    insertatspecificposition( &head, 3, 1 );
    
    putc( '\n', display( head, stdout ) );
    
    insertatspecificposition( &head, 2, 1 );
    
    putc( '\n', display( head, stdout ) );
    
    insertatspecificposition( &head, 4, 3 );
    
    putc( '\n', display( head, stdout ) );
    
    return 0;
}

The program output is

null
1 -> null
1 -> 3 -> null
1 -> 2 -> 3 -> null
1 -> 2 -> 3 -> 4 -> null

If the specified position is greater than or equal to the number of nodes in the list then the new node is appended to the tail of the list.

Positions as indices for arrays in C start from 0.

Of course you need at least one more function that will clear the list that is that will free all the allocated memory.

Upvotes: 1

Related Questions