【问题标题】:How to change the data of a node in Linked list in C?如何更改C中链表中节点的数据?
【发布时间】:2020-06-23 01:37:09
【问题描述】:

结构:

//linked list
struct list
{
  int32_t data;
  struct list *next;
};

struct list *head;

首先,初始化链表(每个节点为0):

void initLinkedList(int size)
{   
    head = (struct list*)malloc(sizeof(struct list)*size);
    struct list *current = head;

    for(int i = 0; i < size; i++)
    {
        (current+i)->data= 0;
    }
}

功能:

void changeNode(int32_t element, int index)
{   
    struct list *current = head;

    for (int i = 0; i < index; i++)
    {
        current = current->next;
        
    } 

    current->data= element;
}

所以基本上,我想用size节点创建一个链表,然后通过函数改变节点的数据。

但是我在函数的这一行遇到了分段错误: current-&gt;localVar = element;

那么,如何在不插入新节点的情况下更改节点的数据?

【问题讨论】:

  • 问题出在你的 changeNode 函数上,你没有分配 current->next 到任何指针。
  • 您可能希望养成使用size_t 索引的习惯,除非负索引是一回事。

标签: c linked-list


【解决方案1】:

您必须考虑是否已请求更改列表中不存在的索引,否则您已接近。您没有以传统方式迭代您的 initLinkedList(您将列表视为数组)作为旁注:在 C 中,无需强制转换 malloc 的返回值,这是不必要的。请参阅:Do I cast the result of malloc?

让我们从您的initLinkedList 函数开始。您已经在全局范围内声明了head(假设),然后用零填充您的列表。在这样做时,您永远不会初始化任何 -&gt;next 指针。你不会得到一个链表——你有一个分配的节点块。

您应该迭代current = current-&gt;next; 并设置每个-&gt;next 指针,而不仅仅是使用偏移量+i。由于在连续块中分配所有节点,您可以像这样初始化您的 data - 但是以后添加的任何节点都不会在内存中连续,并且您的 -&gt;next 指针都不会被初始化。

现在开始你的changeNode 函数。您必须修复 initLinkedList 以初始化 -&gt;next 指针。然后您需要将返回类型从void 更改为struct list*,这样您就可以在成功时返回指向更改节点的指针,或者在失败时返回NULL。目前,您无法知道您的更改是成功还是失败。

做出你可以做的改变:

struct list *changeNode (int32_t element, int index)
{
    struct list *current = head;

    for (int i = 0; i < index; i++) {
        if (!current->next) {
            fputs ("error: request exceeds no. of nodes in list.\n", stderr);
            return NULL;
        }
        current = current->next;
    }
    current->data = element;

    return current;
}

查看一下,如果您还有其他问题,请告诉我。

【讨论】:

    【解决方案2】:

    所以,这里void initLinkedList(int size) 不是创建/初始化链接列表,而是使用size no 动态声明struct list 类型的数组。元素,然后您将使用值0 初始化所有元素。

    要初始化您的linked list 代码:

    void initLinkedList(int size)
    {
        if((head = (struct list*)malloc(sizeof(struct list)*size)) == NULL)
        {
            printf("Memory Unavailable.\n");
            exit(1);
        }
        struct list *current = head;
    
        for(int i = 0; i < size; i++)
        {
            current->data = 0;
            if ((current->next = (struct list*)malloc(sizeof(struct list))) == NULL)
            {
                printf("Memory Unavailable.\n");
                exit(2);
            }
            current = current->next;
        }
        current->next = NULL;
    }
    

    然后到 changeNode,编码:

    void changeNode(int element, int index)
    {
        struct list *current = head;
        int count = 0;
        while(count != index)
        {
            if(current->next)
                current = current->next;
            count++;
        }
        current->data = element;
    }
    

    这里我添加了另一个函数来打印linked list

    void print(struct list *head)
    {
        if(head->next)
        {
            printf("%d", head->data);
            head = head->next;
            print(head);
        }
    }
    

    main():

    int main(void)
    {
        initLinkedList(5);
        changeNode(5, 4);
        print(head);
        delete(head);
        printf("Memory freed.\n");
        return 0;
    }
    

    现在您可以看到示例输出:

    00005
    Memory freed.
    

    还有一件事,如果您对此感到困惑:

    if ((current-&gt;next = (struct list*)malloc(sizeof(struct list))) == NULL)

    我可以帮你。在上面这行代码中,我们正在为current-&gt;next分配内存,并检查内存是否分配成功。

    使用delete()函数释放分配给链表的内存:

    void delete( struct list *head )
    {
      struct list *current = head;
      struct list *next = NULL;
      while(current != NULL)
      {
        next = current->next;
        free(current);
        current = next;
      }
    }
    

    【讨论】:

    • 我怎样才能释放current-&gt;next = (struct list*)malloc(sizeof(struct list))
    • 是的,那将不胜感激
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 2011-09-19
    • 1970-01-01
    • 2019-11-08
    相关资源
    最近更新 更多