首页 > 解决方案 > 使用双指针在 C 中插入链表

问题描述

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

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

#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 

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

标签: cdata-structureslinked-listinsertion

解决方案


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

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

每次*ptr分配列表地址都会更改(如appendNode和 中所示main()

Your list operations are correct, all you need to do is use a temporary pointer to iterate over the list (iter below)

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

(note the use of the dereferenced pointer used with sizeof to set the type-size. If you use the dereferenced pointer to set the size, you eliminate any mistake in setting the actual type needed. Also, if you allocate -- you must validate -- every time)

With that change (and the following change to printList)

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

Your list works just fine, e.g.

Example Use/Output

$ ./bin/lllast2
 23  45  32  11  98

footnotes:

1. While not an error, C generally avoids the use of camelCase or MixedCase variable names in favor of all lower-case while reserving upper-case names for use with macros and constants. It is a matter of style -- so it is completely up to you, but failing to follow it can lead to the wrong first impression in some circles.


推荐阅读