简体   繁体   English

链接列表,在C ++末尾插入

[英]Linked List, insert at the end C++

I was writing a simple function to insert at the end of a linked list on C++, but finally it only shows the first data. 我正在编写一个简单的函数来插入C ++上链表的末尾,但最后它只显示了第一个数据。 I can't figure what's wrong. 我无法弄清楚什么是错的。 This is the function: 这是功能:

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;

}

What you wrote is: 你写的是:

  • if firstNode is null, it's replaced with the single node temp which has no next node (and nobody's next is temp ) 如果firstNode为null,则将其替换为没有下一个节点的单节点temp (并且没有人的nexttemp

  • Else, if firstNode is not null, nothing happens, except that the temp node is allocated and leaked. 否则,如果firstNode不为null,则除了temp节点被分配和泄漏之外没有任何反应。

Below is a more correct code: 以下是更正确的代码:

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

Also, I would suggest adding a constructor to node : 另外,我建议在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) {}
};

Which enables you to create the temp node like this: 这使您可以像这样创建temp节点:

node* temp = new node(name);

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

The problem is that you are replacing the head of the linked list with the new element, and in the process losing the reference to the actual list. 问题是您正在用新元素替换链表的头部,并且在此过程中丢失对实际列表的引用。

To insert at the end, you want to change the while condition to: 要在最后插入,您要将while条件更改为:

while(temp->next != null)

After the loop, temp will point to the last element in the list. 循环之后, temp将指向列表中的最后一个元素。 Then create a new node: 然后创建一个新节点:

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

Then change temp s next to this new node: 然后更改此新节点旁边的temp

temp->next = newNode;

You also do not need to pass firstNode as a reference, unless you want NULL to be treated as a linked list with length 0. In that case, you will need to significantly modify your method so it can handle the case where firstNode is NULL separately, as in that case you cannot evaluate firstNode->next without a segmentation fault. 您也不需要将firstNode作为引用传递,除非您希望将NULL视为长度为0的链接列表。在这种情况下,您需要显着修改您的方法,以便它可以处理firstNodeNULL的情况,因为在这种情况下,您无法firstNode->next没有分段错误的情况下评估firstNode->next

You've made two fundamental mistakes: 你犯了两个根本性的错误:

  1. As you scroll through the list, you roll off the last element and start constructing in the void behind it. 滚动列表时,滚动最后一个元素并开始构建它后面的空白。 Finding the first NULL past the last element is useless. 在最后一个元素之后找到第一个NULL是没用的。 You must find the last element itself (one that has its 'next' equal NULL). 您必须找到最后一个元素(其中一个'next'等于NULL)。 Iterate over temp->next , not temp . 迭代temp temp->next ,而不是temp

  2. If you want to append the element at the end, you must overwrite the last pointer's NULL with its address. 如果要在末尾附加元素,则必须用其地址覆盖最后一个指针的NULL。 Instead, you write the new element at the beginning of the list. 相反,您在列表的开头编写新元素。

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

Note, this gets a bit neater if you make sure never to feed NULL but have all lists always initialized with at least one element. 请注意,如果您确保永远不会提供NULL但所有列表始终使用至少一个元素进行初始化,则会更加整洁。 Also, inserting at the beginning of list is much easier than appending at the end: newnode->next=firstNode; firstNode=newnode 此外,在列表的开头插入比在末尾附加更容易: newnode->next=firstNode; firstNode=newnode newnode->next=firstNode; firstNode=newnode . newnode->next=firstNode; firstNode=newnode

If you don't want to use reference pointer, you could use pointer to pointer. 如果您不想使用引用指针,则可以使用指针指针。 My complete code goes like below: 我的完整代码如下:

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

Understanding the need of the below two variables is key to understanding the problem: 了解以下两个变量的需要是理解问题的关键:

  1. struct node **p: Because we need to link it from the root node created in the main. struct node ** p:因为我们需要从main中创建的根节点链接它。
  2. struct node* last: Because if not used, the original content will be changed with the contents of the next node inside the while loop. struct node * last:因为如果不使用,原始内容将随while循环中下一个节点的内容而改变。 In the end only 2 elements will be printed, the last 2 nodes, which is not desired. 最后只打印2个元素,最后2个节点,这是不希望的。
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;
    }
}
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 loop will return at temp==null in your code instead you need to return last node pointer from while loop like this while循环将在代码中返回temp == null而不是像这样需要从while循环返回最后一个节点指针

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

and assign a new node to next pointer of the returned temp node will add the data to the tail of linked list. 并将新节点分配给返回的临时节点的下一个指针,将数据添加到链表的尾部。

You can use this code: 您可以使用此代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM