链表,在末尾插入C++

Linked List, insert at the end C++

本文关键字:插入 C++ 链表      更新时间:2023-10-16

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

你写的是:

  • 如果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);

您犯了两个基本错误:

  1. 当你在列表中滚动时,你滚动掉最后一个元素,并在它后面的空白中开始构建。您必须找到最后一个元素本身("next"等于NULL的元素)。在temp->next上迭代,而不是在temp上迭代。

  2. 如果要在末尾附加元素,则必须用其地址覆盖最后一个指针的NULL。相反,您可以在列表的开头写入新元素。

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

列表中的最后一个元素从未将其next指针设置为列表中的新元素。

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

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

while(temp->next != null)

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

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

然后更改此新节点旁边的temp s:

temp->next = newNode;

您也不需要将firstNode作为引用传递,除非您希望NULL被视为长度为0的链表。在这种情况下,您将需要显著修改您的方法,以便它能够单独处理firstNodeNULL的情况,因为在这种情况中,如果没有分割错误,您就无法评估firstNode->next

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

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. structnode**p:因为我们需要从main中创建的根节点链接它
  2. struct-node*last:因为如果不使用,原始内容将随着while循环中下一个节点的内容而更改。最后只打印两个元素,最后两个节点,这是不希望的
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;
    }
}
#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

您可以使用以下代码:

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

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