2

所以我对链表如何工作以及它们如何在 C++ 中保持引用有点困惑。

例如,我有一个列表,可以说myList,我想打印它的项目。
我从学校知道我必须将我的列表复制到另一个列表以在打印过程后保持myList相同。

Node* n;
n = myList;
while(n)
{
    printf("%d ",n->val);
    n=n->next;
}

好的,所以我在另一个列表 n 中有一个 myList 的副本(具有相同的指针)。在我遍历 n 之后, myList 是相同的,但具有与 n 相同的指针。

如果 n 改变了为什么 myList 没有改变(相同的指针,对吗?)?

现在如果我说:

Node* n;
n = myList;
n->next = NULL;//or n->next=another node -doesn t matter

现在在第二个例子中 myList 也被改变了。

你能给我解释一下吗?

4

4 回答 4

9

我认为您对实际列表结构和对列表结构的引用之间的区别有些困惑。

在您的第一个示例中,关于遍历列表,您在遍历之前基本上有这种情况,您有两个对同一个列表的引用:

o-->o-->o-->o-->o-->NULL
^
|
 \_ myList, n

遍历列表后看起来像这样:

o-->o-->o-->o-->o-->NULL
^                   ^
|                   |
 \_ myList           \_ n

如果您没有复制对列表头部的引用来遍历它,那么您将在遍历后得到以下结果:

o-->o-->o-->o-->o-->NULL
                    ^
                    |
                     \_ myList

因为您不再有指向列表头部的指针,所以您无法访问该列表。

在你的第二个例子中,你有这个:

o-->o-->o-->o-->o-->NULL
^
|
 \_ myList, n

你把它变成这样:

  _________________
 /                 \
o   o-->o-->o-->o-->NULL
^
|
 \_ myList, n

这种转换改变了列表的实际结构,这将反映在对该列表的所有引用中。

于 2013-01-04T19:56:33.070 回答
4

如果您更改指针n,它将与指针的值mylist不同......它们是两个独立的指针,最初指向同一个对象,因为您n从 in 的值的副本生成 的初始值mylist

话虽如此,如果n自初始化以来,您还没有从 in 的值调整 的值mylist,那么这两个指针指向同一个对象。如果您取消引用任何一个指针并修改它们指向的对象,那么两个指针,因为它们指向同一个对象,将反映对所指向对象的更改。

最后,因为你只是简单地复制mylistinto的值n,所以只有一个链表......你没有制作列表的“深度”副本。因此,如果您修改任一指针指向的实际列表节点,则实际列表将被修改。

于 2013-01-04T19:48:19.483 回答
3

n = myList;n指向与 相同的元素myList。它们本质上是相同的——除了你可以重新分配之外n,但是当它们指向同一个位置时,你并没有真正制作列表的副本——只是指向第一个节点的指针的副本。

因为它们指向同一个位置,所以n->next = NULL;会修改这两个列表。

于 2013-01-04T19:48:36.963 回答
1

您没有创建单独的列表,也没有修改原始列表;您只需使用nto 依次指向每个元素遍历列表(有点像通过数组索引)。

于 2013-01-04T19:53:26.037 回答