Search code examples
clinked-listreversesingly-linked-listfunction-definition

What is the best way to create/reverse a linked list?


I'm a beginner at programming and I've learnt how to reverse a linked list. Below is the code I used to make a linked list with random values and reverse it. I was wondering what the best way to do this would be. Thanks for your suggestions! Have a great day!

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

// node
typedef struct node{
    int number;
    struct node *next;
}node;

// functions
node *reversedList(node *head);
void printList(node *head);
node *create(int size);

int main(void)
{
    srand(time(0));
    // ........
}

node *reversedList(node *curr)
{
    // a->b->c->d
    // d->c->b->a
    node *previous = NULL;
    while(curr->next != NULL)
    {
        node *curr_temp = curr->next;
        curr->next = previous;
        previous = curr;
        curr = curr_temp;
    }
    curr->next = previous;
    return curr;
}

void printList(node *head)
{
    if (head == NULL)
        return;
    printf("%d ",head->number);
    printList(head->next);
}

node *create(int size)
{
    if(size == 0)
        return NULL;
    node *n = malloc(sizeof(node));
    n->number = rand() % 10;
    n->next = create(size - 1);
    return n;   
}

Solution

  • The best way to reverse a singly-linked list is to reverse it without invoking undefined behavior

    In your function reversedList you do not check whether the passed pointer curr is equal to NULL. So the expression in the while loop

    while(curr->next != NULL)
    

    can invoke undefined behavior.

    The function can be defined the following way

    node * reversedList( node *head )
    {
        // a->b->c->d
        // d->c->b->a
    
        node *curr = head;
        head = NULL;
    
        while ( curr != NULL )
        {
            Node *tmp = curr;
            curr = curr->next;
            tmp->next = head;
            head = tmp; 
        }
    
        return head;
    }
    

    Pay attention to that the parameter of the recursive function printList should be declared with the qualifier const because the list is not changed within the function

    void printList(cosnt node *head);
    

    I would declare and define the recursive function the following way

    FILE * printList( const node *head, FILE *fp )
    {
        if ( head )
        {
            fprintf( fp, "%d ", head->number );
        
            printList( head->next, fp );
        }
    
        return fp;
    }
    

    and in main you could write

    fputc( '\n', printList( head, stdout ) );
    

    Using such a function you could output the list in any stream including a file stream.