【问题标题】:Linked List, insert at the end C++链表,在末尾插入 C++
【发布时间】:2013-11-21 15:47:09
【问题描述】:

我正在编写一个简单的函数来插入 C++ 链表的末尾,但最后它只显示第一个数据。我不知道出了什么问题。这是函数:

void InsertAtEnd (node* &firstNode, string name){

        node* temp=firstNode;

        while(temp!=NULL) temp=temp->next;

            temp = new node;
        temp->data=name;
        temp->next=NULL;

        if(firstNode==NULL) firstNode=temp;

}

【问题讨论】:

    标签: c++ linked-list


    【解决方案1】:

    你写的是:

    • 如果firstNode 为空,则替换为单个节点temp 没有下一个节点(没有人的nexttemp

    • 否则,如果firstNode 不为空,则什么都不会发生,除了temp 节点被分配和泄露。

    下面是更正确的代码:

    void insertAtEnd(node* &first, string name) {
        // create node
        node* temp = new node;
        temp->data = name;
        temp->next = NULL;
    
        if(!first) { // empty list becomes the new node
            first = temp;
            return;
        } else { // find last and link the new node
            node* last = first;
            while(last->next) last=last->next;
            last->next = temp;
        }
    }
    

    另外,我建议给node添加一个构造函数:

    struct node {
        std::string data;
        node* next;
        node(const std::string & val, node* n = 0) : data(val), next(n) {}
        node(node* n = 0) : next(n) {}
    };
    

    这使您可以像这样创建temp 节点:

    node* temp = new node(name);
    

    【讨论】:

      【解决方案2】:

      你犯了两个根本性错误:

      1. 当您滚动列表时,您会滚出最后一个元素并开始在其后面的空隙中构建。找到最后一个元素之后的第一个 NULL 是没有用的。您必须找到最后一个元素本身(其“下一个”等于 NULL 的元素)。迭代temp->next,而不是temp

      2. 如果要在末尾追加元素,必须用其地址覆盖最后一个指针的 N​​ULL。相反,您将新元素写在列表的开头。

      void InsertAtEnd (node* &firstNode, string name)
      {
         node* newnode = new node;
         newnode->data=name;
         newnode->next=NULL;
      
         if(firstNode == NULL)
         {
              firstNode=newnode;
         }
         else
         {
              node* last=firstNode;
              while(last->next != NULL) last=last->next;
              last->next = newnode;
         }
      }
      

      注意,如果你确保从不提供 NULL 但始终使用至少一个元素初始化所有列表,这会变得更简洁。此外,在列表开头插入比在末尾追加要容易得多:newnode->next=firstNode; firstNode=newnode

      【讨论】:

        【解决方案3】:

        列表中的最后一个元素永远不会将next 指针设置为列表中的新元素。

        【讨论】:

          【解决方案4】:

          问题是您正在用新元素替换链表的头部,并且在此过程中丢失了对实际列表的引用。

          要在末尾插入,您要将while 条件更改为:

          while(temp->next != null)
          

          循环之后,temp 将指向列表中的最后一个元素。然后新建一个节点:

          node* newNode = new node;
          newNode->data = name;
          newNode->next = NULL;
          

          然后在这个新节点旁边更改temps:

          temp->next = newNode;
          

          您也不需要传递 firstNode 作为参考,除非您希望 NULL 被视为长度为 0 的链表。在这种情况下,您需要显着修改您的方法以便它可以处理firstNode 分别为 NULL 的情况,因为在这种情况下,您无法在没有分段错误的情况下评估 firstNode->next

          【讨论】:

            【解决方案5】:

            如果你不想使用引用指针,你可以使用指向指针的指针。我的完整代码如下:

            void insertAtEnd(struct node **p,int new_data)
            {
                struct node *new_node=(struct node *)malloc(sizeof(struct node));
                new_node->data=new_data;
                new_node->next=NULL;
                if((*p)==NULL)//if list is empty
                {
                    *p=new_node;
                    return;
                }
                struct node* last=*p;//initailly points to the 1st node
                while((last)->next != NULL)//traverse till the last node
                    last=last->next;
                last->next=new_node;
            }
            void printlist(struct node *node)
            {
                while(node != NULL);
                {
                    printf("%d->",node->data);
                    node=node->next;
                }
            }
            int main()
            {
                struct node *root=NULL;
                insertAtEnd(&root,1);
                insertAtEnd(&root,2);
                insertAtEnd(&root,3);
                insertAtEnd(&root,4);
                insertAtEnd(&root,5);
                printlist(root);
            return 0;
            }    
            

            了解以下两个变量的需求是理解问题的关键:

            1. struct node **p:因为我们需要从main中创建的根节点链接它。
            2. struct node* last:因为如果不使用的话,原来的内容会随着while循环内下一个节点的内容而改变。最后只打印 2 个元素,即最后 2 个节点,这是不需要的。

            【讨论】:

              【解决方案6】:
              void addlast ( int a)
              {
              
                  node* temp = new node;
                  temp->data = a;
                  temp->next = NULL;
                  temp->prev=NULL;
                  if(count == maxnum)
                  { 
                      top = temp;
                      count++; 
                  } 
                  else
                  { 
                      node* last = top;
                      while(last->next)
                          last=last->next;
                      last->next = temp;
                  }
              }
              

              【讨论】:

              • 请阅读有关纯代码答案的信息:meta.*.com/a/303605/4284627
              • 欢迎来到 Stack Overflow!虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。不鼓励仅使用代码回答。
              【解决方案7】:
              #include <bits/stdc++.h>
              
              using namespace std;
              
              class Node
              {
              public:
                  int data;
                  Node *next;
              };
              
              void append(Node *first, int n)
              {
                  Node *foo = new Node();
                  foo->data = n;
                  foo->next = NULL;
              
                  if (first == NULL)
                  {
                      first = foo;
                  }
                  else
                  {
                      Node *last = first;
                      while (last->next)
                          last = last->next;
                      last->next = foo;
                  }
              }
              
              void printList(Node *first)
              {
                  while (first->next != NULL)
                  {
                      first = first->next;
                      cout << first->data << ' ';
                  }
              }
              
              int main()
              {
                  Node *node = new Node();
                  append(node, 4);
                  append(node, 10);
                  append(node, 7);
              
                  printList(node);
              
                  return 0;
              }
              

              输出:4 10 7

              【讨论】:

              • 请在您的回答中提供更多详细信息。正如目前所写的那样,很难理解您的解决方案。
              【解决方案8】:

              您可以使用此代码:

              void  insertAtEnd(Node* firstNode, string name)
              {
                  Node* newn = new Node;              //create new  node
                  while( firstNode->next != NULL )    //find the last element in yur list
                      firstNode = firstNode->next;    //he is the one that points to NULL 
                  firstNode->next = newn;             //make it to point to the new element
                  newn->next = NULL;      //make your new element to be the last (NULL)
                  newn->data = name;      //assign data.
              }
              

              【讨论】:

                【解决方案9】:
                void InsertAtEnd (node* &firstNode, string name){
                
                        node* temp=firstNode;
                
                        while(temp && temp->next!=NULL) temp=temp->next;
                
                       node * temp1 = new node;
                        temp1->data=name;
                        temp1->next=NULL;
                       if(temp==NULL)
                           firstNode=temp1;
                       else
                           temp->next= temp1;
                
                
                }
                

                while 循环将在代码中的 temp==null 处返回,而您需要像这样从 while 循环返回最后一个节点指针

                while(temp && temp->next!=NULL) temp=temp->next;
                

                并为返回的临时节点的下一个指针分配一个新节点,将数据添加到链表的尾部。

                【讨论】: