使用双指针在C中插入链表

Linked List Insertion in C using double pointer

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

谁能帮我解决这个问题?

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

}

Ir 打印

 11  98 

这里的问题是什么引起的?

替换:

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;

你的问题是你在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 */
} 

您的列表工作得很好,例如

例子Use/Output

$ ./bin/lllast2
 23  45  32  11  98

脚注:

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