简体   繁体   English

我很困惑为什么这个链表实现有效

[英]I'm confused on why this Linked List implementation works

I've just recently gotten into linked lists and I'm adding my own "add to end" function.我最近刚刚进入链接列表,并且正在添加我自己的“添加到结尾”功能。

void insert_at_end(Node** head, Node* node)
{
    Node* temp;

    temp = *head;

    if (temp == NULL) // linked list is empty
    {
        *head = node;
    }
    else
    {
        while (temp->pNext != NULL)
        {
            temp = temp->pNext;
        }
    temp->pNext = node;
    }
}

Originally I was doing temp != NULL instead of temp->pNext != NULL because I thought that way it would take me to the very LAST node, since it stops looping when temp still has data before it reaches NULL.最初我在做temp != NULL而不是temp->pNext != NULL因为我认为这样它会带我到最后一个节点,因为当 temp 在达到 NULL 之前仍有数据时它会停止循环。 Wouldn't temp->pNext != NULL stop at the 2nd to last node? temp->pNext != NULL不会停在倒数第二个节点吗? Since it stops looping when it realizes that the last nodes next pointer is NULL, it does not travel to that node?因为当它意识到最后一个节点的 next 指针为 NULL 时它停止循环,它不会传播到那个节点?

Thanks guys, If I need to clear anything up from that word vomit let me know.谢谢大家,如果我需要从呕吐这个词中清除任何内容,请告诉我。

Wouldn't temp->pNext != NULL stop at the 2nd to last node? temp->pNext != NULL不会停在倒数第二个节点吗?

No. Here is the pictorial representation for ease of understanding.不。为了便于理解,这里是图示。

With temp != NULL , temp will be pointing to NULL :使用temp != NULLtemp将指向NULL

 +---+    +---+    +---+
 | 1 |--->| 2 |--->| 3 |---> NULL
 +---+    +---+    +---+      ^
                              |
                             temp

As you see temp is iterating until it becomes NULL , at which point you cannot attach anything to the final node because you're past it.正如您所看到的temp正在迭代直到它变为NULL ,此时您无法将任何内容附加到最终节点,因为您已经过去了。


With temp->pNext != NULL , temp will be pointing to last node.使用temp->pNext != NULLtemp将指向最后一个节点。

 +---+    +---+    +---+
 | 1 |--->| 2 |--->| 3 |---> NULL
 +---+    +---+    +---+
                     ^
                     |
                    temp

Here temp will iterate till its next node is NULL .这里temp将迭代,直到它的下一个节点为NULL That means you're pointing to the final node and you can use that pointer to adjust that node to point to a new one with temp->pNext = node :这意味着您指向最后一个节点,您可以使用该指针调整该节点以指向一个具有temp->pNext = node的新temp->pNext = node

 +---+    +---+    +---+    +---+
 | 1 |--->| 2 |--->| 3 |--->| 4 |---> NULL
 +---+    +---+    +---+    +---+
                     ^
                     |
                    temp

As an aside, you may also want to add the extra safety of ensuring the node you're given points to NULL , on the off chance the caller may forget to do that.顺便说一句,您可能还想增加额外的安全性,以确保您获得指向NULL的节点, NULL调用者可能忘记这样做。 That's as simple as adding this line to the start of the function:这就像将这一行添加到函数的开头一样简单:

node->pNext = NULL;

Let's make some analogy.让我们打个比方。

  • Each node is a station.每个节点都是一个站。
  • NULL is your stop station. NULL是您的停靠站。
  • while (temp->pNext != NULL) { temp = temp->pNext; } while (temp->pNext != NULL) { temp = temp->pNext; } means drive and visit each station until reach the stop station. while (temp->pNext != NULL) { temp = temp->pNext; }表示开车并访问每个站点,直到到达停止站点。
  • When you reach the stop station, an additional station is needed to be added by temp->pNext = node;到达停靠站时,需要通过temp->pNext = node;添加一个额外的站temp->pNext = node;

Now the former stop station followed by the new added stop station(implicitly the new NULL ) is not a stop station, but the penultimate station to be visited.现在,前一个停靠站和新添加的停靠站(隐式新的NULL不是停靠站,而是要访问的倒数第二个站。

have a reference for simple linked list concept 有一个简单链表概念的参考

let us take an example让我们举个例子

consider考虑

struct node          
{
  int data;// data which you want to feed.
  struct node *next;// gona hold the address of the next data, so that link can be established
}*root,*p; // root is the starting reference to your linked list

case 1: you dont insert any element and your linked list is empty.情况 1:您没有插入任何元素并且您的链表为空。 Now when you insert a new data 10.it will check for any data in the global pointer reference to your linked list, if, the pointer seems to be NULL, then it means your liked list is empty.The memory stack will be created like this.现在,当您插入新数据时 10.它会检查全局指针引用中指向您的链表的任何数据,如果指针似乎为 NULL,则表示您喜欢的列表为空。内存堆栈将被创建如下这个。

10 10

1000 1000

10 is the data, 1000 is its address. 10 是数据,1000 是它的地址。

case 2: adding an element at its back.you want to add, data 20 to your linked list.you will be looking whether the linked list is empty or not first, using your global linked list address reference(it will be a pointer variable, holding your linked list 1st address, as per your code)情况2:在它的后面添加一个元素。你想将数据20添加到你的链表中。你将首先使用全局链表地址引用(它将是一个指针变量)查看链表是否为空,根据您的代码,持有您的链表第一个地址)

now when we see root->data is not null 1000->data is 10现在当我们看到 root->data is not null 1000->data is 10

we go for root->next which is null, which we come to know that this is the last node.我们去 root->next ,它是空的,我们知道这是最后一个节点。 1000->next is NULL 1000->下一个是NULL

and we insert the new node address to the root->next so that a link is created to the newly inserted node.并且我们将新节点地址插入到 root->next 中,以便创建到新插入节点的链接。

stack will be created like this堆栈将像这样创建

10 20 10 20

1000 1004 1000 1004

case3: now you want to add another data say 30 to the end of list again.案例3:现在您想再次添加另一个数据,例如 30 到列表的末尾。 just follow the same as case 2.只需按照与案例 2 相同的方法操作即可。

check for the node which is currently null, ie root->next == NULL, for this you use a loop to find the node which is currently in last, like this.检查当前为空的节点,即 root->next == NULL,为此您使用循环来查找当前位于最后的节点,如下所示。

 struct node *temp; // creating a temp node which will be the new node we will insert
 temp = (struct node *)malloc(sizeof(struct node));// allocating the size for the temp node, same as the size of previous nodes.
 p = root;// i am giving my starting address to pointer p, i traverse the node with pointer p only, since i dont want to loose my root starting address.
 while(p->next != NULL)// checking for the last node
    p = p->next;// if last node not found, just move to next node, and see whether it is last node or not
 p->next = temp;// if last node is found, put the address of newly created temp node to the node previously found last in the linked list.
 temp->data = element;// feeding data to the temp node.
 temp->next = NULL;// keeping temp node as last, it is necessary to say temp wont has any more node connected.

NOTE dont think this is just a temp node, and will disappear once we come out of function, it is playing with pointer, so it wont destroyed until, the owner wont destroy it.注意不要认为这只是一个临时节点,一旦我们退出函数就会消失,它正在玩指针,所以它不会销毁,直到所有者不会销毁它。

flow will be流量将是

newly created temp address is 1008新创建的临时地址是 1008

1000->next is 1004 1000->接下来是1004

1004->next is NULL 1004->下一个是NULL

so, 1004->next will hold 1008 now所以,1004->next 现在将持有 1008

then,1008->data will be 30那么,1008->数据将是30

then, 1008->next will be NULL然后,1008->next 将为 NULL

stack will be created like this堆栈将像这样创建

10 20 30 10 20 30

1000 1004 1008 1000 1004 1008

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

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