简体   繁体   中英

How to create a doubly circular linked list with a head and tail pointer in C?

I'm currently working on the following code in order to create a doubly circular linked list in C. The code does work when given 2 or 3 numbers as argument, but starting a fourth one some numbers start to disappear from the newly created list for some odd reason.

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

typedef struct s_node
{
        int                             value; // each node contains a integer storing an arbitrary value
        struct s_node   *next;
        struct s_node   *prev;
}                               t_node;

static void     create(t_node **head, t_node **tail, int value, int i)
{
        t_node  *tmp; // create temporary node
        t_node  *result; // create the new node

        tmp = *head;
        result = malloc(sizeof(t_node)); // malloc the new node
        if (!result)
                return ;
        result->value = value;
        result->next = NULL;
        if (*head == NULL) // if the head is NULL, result is the first node to be added
        {
                result->prev = NULL;
                *head = result;
                return ;
        }
        while (tmp->next != NULL && i-- > 0)
                tmp = tmp->next; // parse the linked list until the end
        tmp->next = result; // set result as the next pointer to the last element of the linked list        result->prev = tmp; // set the head has to the previous pointer of the new node
        *tail = result; // tail is now the new node
        (*tail)->next = *head; //link the tail's next pointer to the head to make it circular
        (*head)->prev = *tail; // link the head's previous pointer to make it backwards circular
}

void    save(t_node **head, t_node **tail, int argc, char **argv)
{
        int     i;

        i = 1;
        while (i < argc) // go through the list of given numbers as argument
        {
                create(head, tail, atoi(argv[i]), i); // append a new node to the linked list
                i++;
        }
}

int     main(int argc, char **argv)
{
        t_node  *head;
        t_node  *tail;
        t_node  *tmp;
        int     i;

        i = 4;
        head = NULL;
        tail = NULL;
        if (argc == 0)
                return (0);
        save(&head, &tail, argc, argv);
        tmp = head;
        while (tmp->next != NULL && i-- > 0)
        {
                printf("%d - ", tmp->value);
                tmp = tmp->next;
        }
        printf("\n");
        return (0);
}

When compiled and executed with two arguments as follows:

./a.out 10 20

returns the following (which is correct):

10 - 20 - 10 - 20 -

When executed with three arguments (10, 20 and 30), the following is printed (which is correct):

10 - 20 - 30 - 10 -

However, when a fourth number is added to the list (10, 20, 30 and 40), the following incorrect list is printed:

10 - 20 - 40 - 10 -

Number 30 disappears, and I really don't understand why. Could someone help me out here?

I found aa bug in main

        int     i;

        i = 4;

change to this

while (argc-- > -1)

do not declare t .

another bug is in function create, change to this

        --i;
        while (--i){
                tmp = tmp->next; // parse the linked list until the end
        }

I run in windows, it works fine.

EDIT: some variable can declared global

typedef struct s_t_node
{
    int value;
    struct s_t_node *prev, *next;
} t_node;

t_node *head=NULL, *tmp=NULL, *tail=NULL;

void create(int value){
        t_node* result=malloc(sizeof(t_node));
        result->value=value;
        result->prev=NULL;
        result->next=NULL;
        if(head==NULL){
                head=result;
                tail=result;
                return;
        }
        tmp=head;
        while(tmp->next)
                tmp=tmp->next;
        tmp->next=result;
        result->prev=tmp;
}

int main(int argc, char const *argv[])
{
        if (argc==1)
                return 0;
        for (int i = 1; i < argc; ++i)
        {
                create(atoi(argv[i]));
        }
        tmp=head;
        while(tmp->next)
                tmp=tmp->next;
        tail=tmp;
        head->prev=tail;
        tail->next=head;
        tmp=head;
        argc-=2;
        do{
                printf("%d - ", tmp->value);
                tmp=tmp->next;
        }while(argc--);

        return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM