2

So I wanted to create a doubly linked circular list with the node structure:

typedef struct Node { //node structure
    int value;
    struct Node *next;
    struct Node *previous;
} node;

At first, I had created my list as follows:

//allocate memory for the nodes
    node *first = malloc(sizeof(*first));
    node *second = malloc(sizeof(*second));
    node *third = malloc(sizeof(*third));
    node *fourth = malloc(sizeof(*fourth));
    node *fifth = malloc(sizeof(*fifth));

    { //define the nodes and link them together.(circular linked list)
        first->value = 1;
        first->next = second;
        first->previous = fifth;

        second->value = 2;
        second->next = third;
        second->previous = first;

        third->value = 3;
        third->next = fourth;
        third->previous = second;

        fourth->value = 4;
        fourth->next = fifth;
        fourth->previous = third;

        fifth->value = 5;
        fifth->next = first;
        fifth->previous = fourth;
    }

But then I realized that I do not know if the list should consist of 5 elements and wanted to ask the user about the size of the list. The problem is that when I tried to implement a function called createList() and pass the list size as a parameter, I have no clue of how I should create a such list. I thought of creating a temporary pointer first with ->next and ->previous values as NULL but then how would I iterate through the input n and create new nodes if the next node is NULL?

Thanks

Huzo
  • 1,652
  • 1
  • 21
  • 52
  • 8
    Try to do it all on paper first. Come up with a generic way to add a node to the list. And as a general hint: Keep pointers to the head *and the tail* of the list. Modify the tail when you append a node to the end of the list. – Some programmer dude Feb 19 '18 at 07:30

1 Answers1

1

you have to create new node n(input size) times and append to the tail of the linked list, you can use any looping construct to create new nodes, below is a sample code. Edited: condition for circular doubly linked list, earlier i'vent notice that you have asked for circular dll, i thought it was simply dll.

#include<stdio.h>
#include<stdlib.h>
typedef struct Node { //node structure
    int value;
    struct Node *next;
    struct Node *previous;
} node;

void createList(struct Node ** head, int size) {

    // temp variable to iterate list
    struct Node *temp = *head;
    int val;
    while (size--) {
        scanf("%d", &val);


        if (temp == NULL) {
            // create head node for empty linked list;
            struct Node *node = (struct Node*)malloc(sizeof( Node));
            node->previous = NULL;
            node->next = NULL;
            node->value = val;
            *head = node;
            temp = node;
        } else {
            // if head node exists append the numbers at the end of the linkedlist
            struct Node *node = (struct Node*)malloc(sizeof(struct Node));
            node->previous = temp;
            node->next = NULL;
            node->value = val;
            temp->next = node;
            temp = temp->next;
        }
    }

    // for circular linked list
    temp->next = *head;
    (*head)->previous = temp;
}

void printList (struct Node *head) {
    node *temp = head;
    while (head->next != temp) {
        printf("%d\n", head->value);
        head = head->next;
    }
    // print last node
    printf("%d\n", head->value);
}
int main () {

    struct Node *head = NULL;
    int size;
    scanf("%d", &size);
    createList(&head, size);
    printList(head);
    return 0;
}
vicky
  • 189
  • 2
  • 9
  • everything looks fine and understandable except the `**head` parameter in the `createList` function. why is it a pointer of a pointer? – Huzo Feb 19 '18 at 07:51
  • 1
    we are modifying the list thats why we have to pass the address of the *head, if you wont pass the address of *head value of *head still points to NULL, check out printList function we are iterating the list and modifying the *head in each iteration inside the function since it create a new copy of *head inside the function stack but it doesn't change the original *head after the printList function completed – vicky Feb 19 '18 at 07:56
  • You define `typedef struct Node node;` but continue to use, e.g. `struct Node *head` instead of `node *head` -- any reason in particular? What happens if the user accidentally enters `a10` as the input? `node *node = malloc (sizeof *node);` is sufficient, but you need to validate the allocation succeeded (although I would recommend changing the `typedef` to `node_t` if you are going to use `node`), and see [**Do I cast the result of malloc?**](http://stackoverflow.com/q/605845/995714) – David C. Rankin Feb 19 '18 at 07:56
  • Actually i havent seen that one i just copied hugo's struct type and wrote down the main source code, yes we have to use here node here, and also it was a pain writing too long struct Node * if i notice that typedef is there i just use node. – vicky Feb 19 '18 at 07:58
  • 2
    Also in a *circular* list `tail->next` points to `head` and `head->prev` points to `tail`. (and the `typedef` is with the `struct Node` declaration) – David C. Rankin Feb 19 '18 at 07:59
  • 1
    printlist has an exit condition `head != NULL` it is a circular list - it won't work. this implementation is not for a circular list – Omer Dagan Feb 19 '18 at 08:07
  • 1
    yeah i've updated the code, i havent notice that it was a circular dll. – vicky Feb 19 '18 at 08:19
  • Everything is clear now. Thanks for the intuitive code. – Huzo Feb 19 '18 at 08:28