【问题标题】:How to create a doubly circular linked list with a head and tail pointer in C?如何在C中创建带有头尾指针的双循环链表?
【发布时间】:2021-09-16 12:46:45
【问题描述】:

我目前正在编写以下代码,以便在 C 中创建一个双向循环链表。当给定 2 或 3 个数字作为参数时,该代码确实有效,但从第四个数字开始,一些数字开始从新的出于某种奇怪的原因创建了列表。

#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);
}

当使用如下两个参数编译和执行时:

./a.out 10 20

返回以下内容(正确):

10 - 20 - 10 - 20 -

当使用三个参数(10、20 和 30)执行时,会打印以下内容(正确):

10 - 20 - 30 - 10 -

但是,当将第四个数字添加到列表中时(10、20、30 和 40),将打印以下错误列表:

10 - 20 - 40 - 10 -

30 号消失了,我真的不明白为什么。有人可以帮我吗?

【问题讨论】:

  • 你应该学习如何使用调试器逐行执行你的代码,检查每一步的变量以确保它们的值是你所期望的。
  • 这绝对是一个公平的观点。我猜你说的是 Valgrind 还是 GDB?
  • 新插入后的下一个节点不一定是头节点。您的create 似乎是“在任何地方插入”和“在末尾插入”的混合体。
  • 你的描述让我吃惊。在循环双链表中,如果为空,则头和尾应指向第一个插入的新节点。如果不为空,则不需要迭代到末尾,因为 tail 和 head->prev 都应该指向它。请描述你所谓的双链循环列表的结构,对于没有节点,一个节点,两个节点和三个节点的情况。解释您希望每个指针指向的位置。
  • 请解释为什么您认为循环列表中需要尾部引用?如果它真的是循环的,那么非空列表中的尾部总是等于head-&gt;prev,那么你为什么要为此浪费一个单独的成员呢?为什么要测试tmp-&gt;next != NULL?在循环列表中没有NULL 指针...您确定需要循环 列表,还是误解?

标签: c data-structures linked-list


【解决方案1】:

我在 main 中发现了一个错误

        int     i;

        i = 4;

改成这个

while (argc-- > -1)

不要声明t。

另一个错误是在函数创建中, 改成这个

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

我在windows下运行,效果很好。

编辑:一些变量可以声明为全局变量

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;
}

【讨论】:

  • 你可能有一些东西在这里。我只是不确定它是什么。请添加更多描述性词语来描述发生了什么,问题出在哪里?
猜你喜欢
  • 2013-11-15
  • 2023-03-11
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多