'Returning a pointer to the beginning of a linked list after adding nodes?

struct node {
    struct node *next;
    int num;
} Node;


Node *insert(int i) {
    Node *head;
    for (int c = 0; c < i; c++) {
        head = malloc(sizeof(Node));
        head.num = i;
        head = head->next;
    }
}

The insert function is supposed to create a linked list and add numbers from 0 to i to that linked list. However, it is also supposed to return a pointer to the beginning of the list/the list itself and I can't seem to figure out how to do it. I've tried to make a pointer and set it equal to head after adding the first node, but it only returns the first node and not the entire list. Can someone please help? Thanks.



Solution 1:[1]

You probably want to remember the previous node, so you can assign its next pointer. When you add a node, set its next pointer to the old head, and it now becomes the new head of the list. Which you can just return after the last iteration of the loop.

Node *insert(int i) {
    Node *head, *prev = NULL;
    for (int c = 0; c < i; c++) {
        head = malloc(sizeof(Node));
        head->num = i;
        head->next = prev;
        prev = head;
    }
    return head;
}

Update: to insert each new element at the end of the list, you need a bit more bookkeeping:

Node *insert(int i) {
    Node *last_node = NULL;
    Node *first_node = NULL;
    for (int c = 0; c < i; c++) {
        Node *node = malloc(sizeof(Node));
        node->num = i;
        node->next = NULL;
        if (!last_node) {
            // Remember the first node, so we can return it.
            first_node = node;
        }
        else {
            // Otherwise, append to the existing list.
            last_node->next = node;
        }
        last_node = node;
    }
    return first_node;
}

Solution 2:[2]

It is as simple as introducing another variable. You currently have head to track the head of the list; add another to track the tail of the list:

struct node {
    struct node *next;
    int num;
} Node;

Node *insert(int i) {
    Node *head;
    Node *tail;
    head = malloc(sizeof(Node));
    head.num = 0;
    tail = head;
    for (int c = 1; c < i; c++) {
        // allocate a new node at the end of the list:
        tail->next = malloc(sizeof(Node));
        // set "tail" to point to the new tail node:
        tail = tail->next;
        tail->num = c;
    }

    return head;
}

You could also add a special case for i == 0, if necessary.

By the way - and I realise this is possibly a task given to you as an exercise - but insert is a terrible name for a function that actually creates and fills an entirely new list.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 davmac