繁体   English   中英

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

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

我最近刚刚进入链接列表,并且正在添加我自己的“添加到结尾”功能。

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

最初我在做temp != NULL而不是temp->pNext != NULL因为我认为这样它会带我到最后一个节点,因为当 temp 在达到 NULL 之前仍有数据时它会停止循环。 temp->pNext != NULL不会停在倒数第二个节点吗? 因为当它意识到最后一个节点的 next 指针为 NULL 时它停止循环,它不会传播到那个节点?

谢谢大家,如果我需要从呕吐这个词中清除任何内容,请告诉我。

temp->pNext != NULL不会停在倒数第二个节点吗?

不。为了便于理解,这里是图示。

使用temp != NULLtemp将指向NULL

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

正如您所看到的temp正在迭代直到它变为NULL ,此时您无法将任何内容附加到最终节点,因为您已经过去了。


使用temp->pNext != NULLtemp将指向最后一个节点。

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

这里temp将迭代,直到它的下一个节点为NULL 这意味着您指向最后一个节点,您可以使用该指针调整该节点以指向一个具有temp->pNext = node的新temp->pNext = node

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

顺便说一句,您可能还想增加额外的安全性,以确保您获得指向NULL的节点, NULL调用者可能忘记这样做。 这就像将这一行添加到函数的开头一样简单:

node->pNext = NULL;

让我们打个比方。

  • 每个节点都是一个站。
  • NULL是您的停靠站。
  • while (temp->pNext != NULL) { temp = temp->pNext; } while (temp->pNext != NULL) { temp = temp->pNext; }表示开车并访问每个站点,直到到达停止站点。
  • 到达停靠站时,需要通过temp->pNext = node;添加一个额外的站temp->pNext = node;

现在,前一个停靠站和新添加的停靠站(隐式新的NULL不是停靠站,而是要访问的倒数第二个站。

有一个简单链表概念的参考

让我们举个例子

考虑

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

情况 1:您没有插入任何元素并且您的链表为空。 现在,当您插入新数据时 10.它会检查全局指针引用中指向您的链表的任何数据,如果指针似乎为 NULL,则表示您喜欢的列表为空。内存堆栈将被创建如下这个。

10

1000

10 是数据,1000 是它的地址。

情况2:在它的后面添加一个元素。你想将数据20添加到你的链表中。你将首先使用全局链表地址引用(它将是一个指针变量)查看链表是否为空,根据您的代码,持有您的链表第一个地址)

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

我们去 root->next ,它是空的,我们知道这是最后一个节点。 1000->下一个是NULL

并且我们将新节点地址插入到 root->next 中,以便创建到新插入节点的链接。

堆栈将像这样创建

10 20

1000 1004

案例3:现在您想再次添加另一个数据,例如 30 到列表的末尾。 只需按照与案例 2 相同的方法操作即可。

检查当前为空的节点,即 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.

注意不要认为这只是一个临时节点,一旦我们退出函数就会消失,它正在玩指针,所以它不会销毁,直到所有者不会销毁它。

流量将是

新创建的临时地址是 1008

1000->接下来是1004

1004->下一个是NULL

所以,1004->next 现在将持有 1008

那么,1008->数据将是30

然后,1008->next 将为 NULL

堆栈将像这样创建

10 20 30

1000 1004 1008

暂无
暂无

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

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