【问题标题】:Linked List Insertion in C using double pointer使用双指针在 C 中插入链表
【发布时间】:2019-04-20 15:57:16
【问题描述】:

您好,我是学习链接列表的新手,我创建了这个示例程序,但它没有填充所有列表,只有最后两个被填充(或者这些覆盖了第一个链接元素)

有人可以帮我解决问题的原因吗?

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

struct node {
    int data;
    struct node *link;
};  

void appendNode(int data, struct node **ptr) {

    struct node *newnode = (struct node*)malloc(sizeof(struct node));

    newnode->data = data;
    newnode->link = NULL;

    if(*ptr == NULL) {
         *ptr = newnode;
    } else {
        while((*ptr)->link != NULL ) {
            *ptr = (*ptr)->link;
        }
        (*ptr)->link = newnode;
    }

}

void printList(struct node *node) 
{ 
  while (node != NULL) 
  { 
     printf(" %d ", node->data); 
     node = node->link; 
  } 
} 

int main() {

    struct node *head = NULL ;

    appendNode(23,&head);
    appendNode(45,&head);
    appendNode(32,&head);
    appendNode(11,&head);
    appendNode(98,&head);
    printList(head);

}

红外打印

 11  98 

是什么导致了这里的问题?

【问题讨论】:

  • 只跟踪最后一个节点而不是在每次要插入时使用while 循环扫描整个列表不是更容易吗?

标签: c data-structures linked-list insertion


【解决方案1】:

您的问题是您正在使用appendNode[1] 中的指针本身进行迭代。每次您将某些内容分配给*ptr 时,这都会更改列表地址,例如

     *ptr = newnode;
     ...
        *ptr = (*ptr)->link;

每次分配*ptr 时,列表地址都会更改(在appendNodemain() 中都可以看到)

你的列表操作是正确的,你需要做的就是使用一个临时指针来遍历列表(iter下面)

void appendNode (int data, struct node **ptr) {

    struct node *newnode = malloc (sizeof *newnode),
        *iter = *ptr;

    if (!newnode) { /* VALIDATE every allocation */
        perror ("malloc-newnode");
        exit (EXIT_FAILURE);
    }

    newnode->data = data;
    newnode->link = NULL;

    if (iter == NULL) {
        *ptr = newnode;
    }
    else {
        while (iter->link != NULL) {
            iter = iter->link;
        }
        iter->link = newnode;
    }
}

(注意使用与sizeof一起使用的解引用指针来设置类型大小。如果使用解引用指针来设置大小,则可以消除设置实际类型时的任何错误需要。另外,如果你分配——你必须每次都验证——)

随着该更改(以及以下更改为printList

void printList (struct node *node) 
{ 
    while (node != NULL) 
    { 
        printf(" %d ", node->data); 
        node = node->link; 
    }
    putchar ('\n');     /* tidy up with newline */
} 

您的列表工作正常,例如

使用/输出示例

$ ./bin/lllast2
 23  45  32  11  98

脚注:

1.虽然不是错误,但 C 通常会避免使用 camelCaseMixedCase 变量名,而是在保留 时使用所有 小写 >大写 用于宏和常量的名称。这是一个风格问题——所以这完全取决于你,但不遵循它可能会在某些圈子中导致错误的第一印象。

【讨论】:

    【解决方案2】:

    替换:

    while((*ptr)->link != NULL ) {
        *ptr = (*ptr)->link;
    }
    (*ptr)->link = newnode;
    

    与:

    struct node* last = *ptr;
    while (last->link) {
        last = last->link;
    }
    last->link = newnode;
    

    虽然将其提取到自己的函数中可能会很好:

    struct node* findLastNode(struct node* ptr) {
        while (ptr->link) {
            ptr = ptr->link;
        }
        return ptr;
    }
    

    那么,在appendNode里面:

    struct node* last = findLastNode(*ptr);
    last->link = newnode;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 1970-01-01
      • 2012-04-20
      • 2020-07-06
      相关资源
      最近更新 更多