了解使用本地引用构建链接列表的逻辑

时间:2018-08-12 18:58:18

标签: c linked-list

下面是使用本地引用逻辑创建链接列表的代码。 无法理解for循环内的代码,尤其是第二行。 (请参见// HERE

有人可以详细说明这种逻辑如何工作。

void push(struct Node** head_ref, int new_data)
{
  struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
  newNode->data = new_data;

  newNode->next = *head_ref;
  *head_ref = newNode;

  return;
}


struct Node* buildWithLocalRef()
{
  int i=0;
  struct Node *head = NULL;
  struct Node **lastptrRef = &head;

  for(i=1;i<6;i++)
  {
    push(lastptrRef,i);
    lastptrRef = &((*lastptrRef)->next); // HERE
  }

  return head;
}

int main()
{
  struct Node* head;

  head = buildWithLocalRef();
  printList(head);
  return 0;
}

1 个答案:

答案 0 :(得分:5)

您看到的技术是通过正向链接建立链接列表。这是从头到尾构建有序列表的最直接,最明智的方法,该列表没有尾指针(而您的指针没有尾指针)。

这里没有“参考”。这不是C ++。这是使用指向指针的指针。变量名被可怕地命名为btw。它是如何工作的:

  1. 列表最初是空的,headNULL
  2. 指向指针lastptrRef的指针将始终保存要填充新的动态节点分配的下一个指针的地址(不是;存在区别)。最初,指向指针的指针保存着head指针的地址,该地址最初为NULL(很有意义,这就是您希望第一个节点挂起的位置)。
  3. 在迭代循环时,将在push中分配一个新节点。将该节点的next指针设置为lastptrRef所指向的指针中的任何值(在函数中作为head_ref传递),然后lastptrRef所指向的指针为更新为新的节点值。
  4. 最后,为lastptrRef赋予刚添加的节点中next成员的地址,然后重复该过程。

在每种情况下,lastptrRef会在进入NULL时保留包含push的指针的地址。此push函数使这一点很难理解。 (稍后会详细介绍)。直接进行正向链接很容易理解,在这种情况下,正向链接将使它变得非常容易理解

struct Node* buildWithLocalRef()
{
    struct Node *head = NULL;
    struct Node **pp = &head;

    for (int i = 1; i < 6; i++)
    {
        *pp = malloc(sizeof **pp);
        (*pp)->data = i;
        pp = &(*pp)->next;
    }
    *pp = NULL;

    return head;
}

在这里,pp始终保存我们将使用新节点分配填充的下一个指针的地址。最初,它保存head的地址。在插入每个节点时,pp会被设置为插入的 latest 节点内next指针的地址,从而使您能够在下一次迭代中继续执行链。循环完成后,ppnext指针的地址保存在列表的 last 节点中(或未插入head的地址) ;请考虑如果将环路完全拉出会发生什么情况。我们希望它是NULL来终止列表,所以执行最后的*pp = NULL;

您发布的代码执行相同的操作,但是以更复杂的方式进行,因为push旨在将项目推入列表的 front (显然)。该函数始终将head_ref指向的指针设置为添加的新节点,并且该节点的next总是首先设置为*head_ref中的旧值。因此,可以通过执行以下操作来构建 stack

struct Node* buildStack()
{
    struct Node *head = NULL;

    for (int i = 1; i < 6; i++)
        push(&head, i);

    return head;
}

现在,如果您打印出结果后的链表,该数字将以相反的顺序输入。实际上,push在这里名不虚传。双重目的来构建前向链表是很有创意的,我会同意的,但是最终它使它有些混乱。