C语言 C链表在末尾插入节点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5797548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:30:28  来源:igfitidea点击:

C linked list inserting node at the end

cinsertlinked-listbinary-tree

提问by schnaader

I'm having some trouble with my insertion method for a linked list in C. It seems to only add at the beginning of the list. Any other insertion I make fail. And this CodeBlocks debugger is so hard to understand I still don't get it. It never gives me value, just addresses in memory. Anyway this is my function. Do you see any reason why it's failing?

我在 C 中的链表插入方法中遇到了一些问题。它似乎只在列表的开头添加。我所做的任何其他插入都失败了。这个 CodeBlocks 调试器太难理解了,我还是不明白。它从来没有给我价值,只是内存中的地址。无论如何,这是我的职责。你看到它失败的任何原因吗?

/* function to add a new node at the end of the list */
int addNodeBottom(int val, node *head){

    //create new node
    node *newNode = (node*)malloc(sizeof(node));

    if(newNode == NULL){
        fprintf(stderr, "Unable to allocate memory for new node\n");
        exit(-1);
    }

    newNode->value = val;

    //check for first insertion
    if(head->next == NULL){
        head->next = newNode;
        printf("added at beginning\n");
    }

    else
    {
        //else loop through the list and find the last
        //node, insert next to it
        node *current = head;
        while(current->next != NULL)
        {
            if(current->next == NULL)
            {
                current->next = newNode;
                printf("added later\n");
            }
            current = current->next;
        }
    }
    return 0;
}

Then in main, only 929 is added.

然后在 main 中,只添加了 929。

   //testing addNodeBottom function
    addNodeBottom(929, head);
    addNodeBottom(98, head);
    addNodeBottom(122, head);
    addNodeBottom(11, head);
    addNodeBottom(1034, head);

回答by schnaader

This code will work. The answer from samplebias is almost correct, but you need a third change:

此代码将起作用。samplebias 的答案几乎是正确的,但您需要进行第三次更改:

int addNodeBottom(int val, node *head){

    //create new node
    node *newNode = (node*)malloc(sizeof(node));

    if(newNode == NULL){
        fprintf(stderr, "Unable to allocate memory for new node\n");
        exit(-1);
    }

    newNode->value = val;
    newNode->next = NULL;  // Change 1

    //check for first insertion
    if(head->next == NULL){
        head->next = newNode;
        printf("added at beginning\n");
    }

    else
    {
        //else loop through the list and find the last
        //node, insert next to it
        node *current = head;
        while (true) { // Change 2
            if(current->next == NULL)
            {
                current->next = newNode;
                printf("added later\n");
                break; // Change 3
            }
            current = current->next;
        };
    }
    return 0;
}

Change 1: newNode->nextmust be set to NULLso we don't insert invalid pointers at the end of the list.

变化1:newNode->next必须设置为NULL这样我们就不会在列表的末尾插入无效的指针。

Change 2/3: The loop is changed to an endless loop that will be jumped out with break;when we found the last element. Note how while(current->next != NULL)contradicted if(current->next == NULL)before.

更改 2/3:将循环更改为无限循环,break;当我们找到最后一个元素时会跳出。注意之前是多么while(current->next != NULL)矛盾if(current->next == NULL)

EDIT: Regarding the while loop, this way it is much better:

编辑:关于while循环,这种方式要好得多:

  node *current = head;
  while (current->next != NULL) {
    current = current->next;
  }
  current->next = newNode;
  printf("added later\n");

回答by samplebias

After you malloca nodemake sure to set node->next = NULL.

你后malloc一个node确保集node->next = NULL

int addNodeBottom(int val, node *head)
{    
    node *current = head;
    node *newNode = (node *) malloc(sizeof(node));
    if (newNode == NULL) {
        printf("malloc failed\n");
        exit(-1);
    }    

    newNode->value = val;
    newNode->next = NULL;

    while (current->next) {
        current = current->next;
    }    
    current->next = newNode;
    return 0;
}    

I should point out that with this version the headis still used as a dummy, not used for storing a value. This lets you represent an empty list by having just a headnode.

我应该指出,在这个版本中,head仍然用作虚拟对象,而不是用于存储值。这使您可以通过只有一个head节点来表示一个空列表。

回答by user2800488

I would like to mention the key before writing the code for your consideration.

在编写代码之前,我想提一下关键供您考虑。

//Key

//钥匙

temp= address of new node allocated by malloc function (member od alloc.h library in C )

temp= malloc 函数分配的新节点地址(C 中的成员 od alloc.h 库)

prev= address of last node of existing link list.

prev= 现有链表的最后一个节点的地址。

next = contains address of next node

next = 包含下一个节点的地址

struct node {
    int data;
    struct node *next;
} *head;

void addnode_end(int a) {
    struct node *temp, *prev;
    temp = (struct node*) malloc(sizeof(node));
    if (temp == NULL) {
        cout << "Not enough memory";
    } else {
        node->data = a;
        node->next = NULL;
        prev = head;

        while (prev->next != NULL) {
            prev = prev->next;
        }

        prev->next = temp;
    }
}

回答by Nikhil Sharma

The new node is always added after the last node of the given Linked List. For example if the given Linked List is 5->10->15->20->25 and we add an item 30 at the end, then the Linked List becomes 5->10->15->20->25->30. Since a Linked List is typically represented by the head of it, we have to traverse the list till end and then change the next of last node to new node.

新节点总是添加在给定链表的最后一个节点之后。例如,如果给定的链表是 5->10->15->20->25 并且我们在最后添加了一个项目 30,那么链表变成了 5->10->15->20->25- > 30。由于链表通常由它的头部表示,我们必须遍历列表直到结束,然后将最后一个节点的下一个节点更改为新节点。

/* Given a reference (pointer to pointer) to the head
   of a list and an int, appends a new node at the end  */


    void append(struct node** head_ref, int new_data)
    {
    /* 1. allocate node */
         struct node* new_node = (struct node*) malloc(sizeof(struct node));

        struct node *last = *head_ref;  /* used in step 5*/

    /* 2. put in the data  */
        new_node->data  = new_data;

    /* 3. This new node is going to be the last node, so make next 
          of it as NULL*/
        new_node->next = NULL;

    /* 4. If the <a href="#">Linked List</a> is empty, then make the new node as head */
        if (*head_ref == NULL)
        {
       *head_ref = new_node;
       return;
        }  

    /* 5. Else traverse till the last node */
        while (last->next != NULL)
        last = last->next;

    /* 6. Change the next of last node */
        last->next = new_node;
        return;    
}

回答by BullyWiiPlaza

This works fine:

这工作正常:

struct node *addNode(node *head, int value) {
    node *newNode = (node *) malloc(sizeof(node));
    newNode->value = value;
    newNode->next = NULL;

    if (head == NULL) {
        // Add at the beginning
        head = newNode;
    } else {
        node *current = head;

        while (current->next != NULL) {
            current = current->next;
        };

        // Add at the end
        current->next = newNode;
    }

    return head;
}

Example usage:

用法示例:

struct node *head = NULL;

for (int currentIndex = 1; currentIndex < 10; currentIndex++) {
    head = addNode(head, currentIndex);
}

回答by Ashley Duncan

I know this is an old post but just for reference. Here is how to append without the special case check for an empty list, although at the expense of more complex looking code.

我知道这是一个旧帖子,但仅供参考。以下是如何在没有特殊情况检查的情况下追加空列表,尽管代价是看起来更复杂的代码。

void Append(List * l, Node * n)
{
    Node ** next = &list->Head;
    while (*next != NULL) next = &(*next)->Next;
    *next = n;
    n->Next = NULL;
}