Moonwalker
Moonwalker

Reputation: 21

How to insert data into Doubly Linked List using for loop in C

I made a Doubly Linked List, but instead of manually assigning the values (10, 20, 30) I want to make a for loop and put the data that way to make it efficient. I did it in Singly Linked List but the same is not happening over here and only backward_traversing function works.

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

typedef struct Node
{
    int value;
    struct Node *next_link;
    struct Node *prev_link;
} Node;

Node *create_node(int value)
{
    Node *new_node = malloc(sizeof(Node));
    new_node->value = value;
    new_node->next_link = NULL;
    new_node->prev_link = NULL;

    return new_node;
}

void forward_traversing(Node *head)
{
    Node *temp = head;

    while (temp != NULL)
    {
        printf("%d ", temp -> value);
        temp = temp->next_link;
    }
    printf("\n");
}

void backward_traversing(Node *tail)
{
    Node *temp = tail;

    while (temp != NULL)
    {
        printf("%d ", temp->value);
        temp = temp->prev_link;
    }
    printf("\n");
}

void show_first(Node *head)
{
    printf("%d \n", head->value);
}

void show_last(Node *tail)
{
    printf("%d \n", tail->value);
}

int main()
{
    Node *head, *temp, *tail;

    for (int i = 0; i <= 25; i++){
        temp = create_node(i);
        temp -> next_link = head;
        head = temp;
    }
    
    forward_traversing(head);
    backward_traversing(tail);
    show_first(head);
    show_last(tail);
    
    return 0;
}

Upvotes: 1

Views: 124

Answers (1)

Ian Abbott
Ian Abbott

Reputation: 17503

It is useful to define a type to hold the head and tail pointers of the list since some functions may need to update both the head and tail pointers.

Fundamental operations include:

  • initializing the list
  • various ways to add an element to the list, such as:
    • prepending it to the start of the list
    • appending it to the end of the list
    • inserting it before some other element already on the list
    • (inserting it after some other element can be implemented by inserting it before the next element if it exists, or appending it to the list)
  • various ways to remove an element from the list, such as:
    • removing the first element
    • removing the last element
    • removing an element known to be on the list

Functions can be written to perform those operations, as in the following example based on OP's original code (OP's functions that that took a head pointer or a tail pointer have been changed to take a pointer to the list control structure):

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

typedef struct Node
{
    int value;
    struct Node *next_link;
    struct Node *prev_link;
} Node;

typedef struct List
{
    struct Node *head;
    struct Node *tail;
} List;

Node *create_node(int value)
{
    Node *new_node = malloc(sizeof(Node));
    new_node->value = value;
    new_node->next_link = NULL;
    new_node->prev_link = NULL;

    return new_node;
}

Node *node_next(Node *node)
{
    return node ? node->next_link : NULL;
}

Node *node_prev(Node *node)
{
    return node ? node->prev_link : NULL;
}

void free_node(Node *node)
{
    free(node);
}

void list_init(List *list)
{
    list->head = NULL;
    list->tail = NULL;
}

Node *list_first(List *list)
{
    return list->head;
}

Node *list_last(List *list)
{
    return list->tail;
}

/* Note: existingnode assumed to be on the list if non-null */
/* Note: if existingnode is null, newnode will be prepended to the list */
void list_insert_before(List *list, Node * restrict existingnode,
                        Node * restrict newnode)
{
    if (newnode)
    {
        Node *prev;

        if (existingnode == NULL)
        {
            /* newnode will be prepended before head (if it exists) */
            existingnode = list->head;
        }
        if (existingnode)
        {
            prev = existingnode->prev_link;
            existingnode->prev_link = newnode;
        }
        else
        {
            /* list is empty */
            prev = NULL;
            list->tail = newnode;
        }
        newnode->prev_link = prev;
        newnode->next_link = existingnode;
        if (prev)
        {
            prev->next_link = newnode;
        }
        else
        {
            /* newnode being prepended to the list */
            list->head = newnode;
        }
    }
}

void list_prepend(List *list, Node *node)
{
    /* Note: list->head may be null */
    list_insert_before(list, list->head, node);
}

void list_append(List *list, Node *node)
{
    if (node)
    {
        node->next_link = NULL;
        node->prev_link = list->tail;
        if (list->tail)
        {
            list->tail->next_link = node;
        }
        else
        {
            /* list is empty */
            list->head = node;
        }
        list->tail = node;
    }
}

/* Note: existingnode assumed to be on the list if non-null */
/* Note: if existingnode is null, newnode will be appended to the list */
void list_insert_after(List *list, Node * restrict existingnode,
                       Node * restrict newnode)
{
    if (existingnode == NULL || existingnode == list->tail)
    {
        list_append(list, newnode);
    }
    else
    {
        list_insert_before(list, existingnode->next_link, newnode);
    }
}

/* Note: node assumed to be on the list if non-null */
void list_remove_node(List *list, Node *node)
{
    if (node)
    {
        Node *next = node->next_link;
        Node *prev = node->prev_link;

        if (next)
        {
            next->prev_link = prev;
        }
        else
        {
            list->tail = prev;
        }
        if (prev)
        {
            prev->next_link = next;
        }
        else
        {
            list->head = next;
        }
        node->next_link = NULL;
        node->prev_link = NULL;
    }
}

Node *list_remove_first(List *list)
{
    Node *node = list_first(list);

    list_remove_node(list, node);
    return node;
}

Node *list_remove_last(List *list)
{
    Node *node = list_last(list);

    list_remove_node(list, node);
    return node;
}

void free_list_nodes(List *list)
{
    Node *temp;

    while ((temp = list_remove_first(list)) != NULL)
    {
        free_node(temp);
    }
}

void forward_traversing(List *list)
{
    Node *temp = list_first(list);

    while (temp != NULL)
    {
        printf("%d ", temp->value);
        temp = temp->next_link;
    }
    printf("\n");
}

void backward_traversing(List *list)
{
    Node *temp = list_last(list);

    while (temp != NULL)
    {
        printf("%d ", temp->value);
        temp = temp->prev_link;
    }
    printf("\n");
}

void show_first(List *list)
{
    Node *head = list_first(list);

    if (head)
    {
        printf("%d \n", head->value);
    }
    else
    {
        printf("(empty)\n");
    }
}

void show_last(List *list)
{
    Node *tail = list_last(list);

    if (tail)
    {
        printf("%d \n", tail->value);
    }
    else
    {
        printf("(empty)\n");
    }
}

int main()
{
    List list;
    Node *node;
    int i;

    list_init(&list);
    for (i = 10; i < 50; i += 10)
    {
        node = create_node(i);

        if (node)
        {
            list_append(&list, node);
        }
    }

    printf("Initial list\n");
    forward_traversing(&list);
    backward_traversing(&list);

    printf("Remove first node\n");
    node = list_remove_first(&list);    /* (10), 20, 30, 40 */
    forward_traversing(&list);
    backward_traversing(&list);

    printf("Prepend removed node to start of list\n");
    list_prepend(&list, node);          /* 10, 20, 30, 40 */
    forward_traversing(&list);
    backward_traversing(&list);

    printf("Remove last node\n");
    node = list_remove_last(&list);     /* 10, 20, 30, (40) */
    forward_traversing(&list);
    backward_traversing(&list);
    printf("Append removed node to end of list\n");
    list_append(&list, node);           /* 10, 20, 30, 40 */
    forward_traversing(&list);
    backward_traversing(&list);

    printf("Remove third node\n");
    node = node_next(node_next(list_first(&list))); /* (30) */
    list_remove_node(&list, node);      /* 10, 20, 40 */
    forward_traversing(&list);
    backward_traversing(&list);
    printf("Insert removed node after second node\n");
    list_insert_after(&list, node_next(list_first(&list)), node);
                                        /* 10, 20, 30, 40 */
    forward_traversing(&list);
    backward_traversing(&list);
    printf("Remove previous (third) node again\n");
    list_remove_node(&list, node);      /* 10, 20, 40 */
    forward_traversing(&list);
    backward_traversing(&list);
    printf("Insert removed node before third (original fourth) node\n");
    list_insert_before(&list, node_next(node_next(list_first(&list))),
                       node);           /* 10, 20, 30, 40 */
    forward_traversing(&list);
    backward_traversing(&list);

    printf("First node\n");
    show_first(&list);
    printf("Last node\n");
    show_last(&list);

    free_list_nodes(&list);
    return 0;
}

Output:

Initial list
10 20 30 40 
40 30 20 10 
Remove first node
20 30 40 
40 30 20 
Prepend removed node to start of list
10 20 30 40 
40 30 20 10 
Remove last node
10 20 30 
30 20 10 
Append removed node to end of list
10 20 30 40 
40 30 20 10 
Remove third node
10 20 40 
40 20 10 
Insert removed node after second node
10 20 30 40 
40 30 20 10 
Remove previous (third) node again
10 20 40 
40 20 10 
Insert removed node before third (original fourth) node
10 20 30 40 
40 30 20 10 
First node
10 
Last node
40 

Upvotes: 0

Related Questions