C++ Linked List——一个新的指针,不用于遍历列表可以打印列表吗?

C++ Linked List – a new pointer that is not used to traverse the list CAN print the list?

我在 C++ 中创建了一个简单的动态链表实现,它的头节点为 42,然后提示用户 he/she 是否要将其他数字添加到列表中。

#include <iostream>

using namespace std;

struct Node
{
    int x;
    Node *next;
};

int main(int argc, char** argv)
{
    char choice;

    Node *start = new Node;

    start->next = NULL;
    start->x = 42;

    Node *traverser = start;

    while (1) {
        cout << "Add item to the list (Y/N)? ";
        cin >> choice;

        if (choice == 'Y') {
            traverser->next = new Node;
            traverser = traverser->next;
            traverser->next = NULL;
            cout << "New item: ";
            cin >> traverser->x;
        }
        else {

            cout << "Linked List:\n";
            Node *p;
            for (p = start; p != NULL; p = p->next) {
                cout << p->x << endl;                    //QUESTION HERE!
            }
            cout << "\nProgram dismissed.";
            exit(0);
        }
    }
}

现在,如代码块中所示,问题在于指针 *p。我的链表的头部被命名为 start,而遍历并向列表添加项的指针被命名为 traverser。为什么 *p 仅分配给头部时能够打印列表中的所有内容

p = start

而不是列表的主体。我会明白这适用于打印

cout << "Linked List:\n";
for (traverser = start; traverser != NULL; traverser = traverser->next) {
    cout << traverser->x << endl;
}

但是 *p 能够打印整个列表让我很困惑,很多!

请帮忙。

p 只是一个指针变量,与任何其他变量一样它可以有不同的值,但它指向地址。

p = start

p 开始指向您的第一个节点。

 p = p->next

它开始指向下一个节点。 你哪里糊涂了?

traverser 不包含列表的主体。 start会。

让我们回顾一下你的节目内容:

    Node *start = new Node;

start 将始终指向此处创建的节点。 start 始终是列表的开头。

从这个节点,您可以使用节点 next 成员遍历 整个 列表。

Node *traverser = start;

traverser 最初是与 start 节点相同的节点。 traverser表示列表的end。您不能使用 traverser 遍历列表。使用 traverser 的原因是它简化了在列表末尾插入新节点的过程。

最后一条语句由语句显示

traverser->next = new Node;
traverser = traverser->next;
traverser->next = 0;

最后一条语句告诉我们,我们不能在任何地方跟随 traverser 节点。这是列表的结尾。

所以start是整个列表,start->x是列表中的第一个值。 start->next 是指向列表中下一个元素的指针。

现在,我们不想破坏列表的 start。因此,让我们复制指向第一个元素的指针,并将该副本称为 p。使用 p 查看列表。 p 仅对这一小段代码有用,而 starttraverser 对整个程序有用。

Node* p = start;  
for (; p != NULL; p = p->next) {
     cout << p->x << endl;
 }

打印的最后一个元素将与 traverser指向的元素相同。

*p 能够打印整个列表,因为 *p(最初)指向列表的开头。在列表开始之后,是列表的主体,您链接到

if (choice == 'Y') {
        traverser->next = new Node;
        traverser = traverser->next;
        traverser->next = NULL;
        cout << "New item: ";
        cin >> traverser->x;
    }

理解到这里,最初traverser和start都操作同一个对象。用外行的话来说,当你使用指针时,你不是在克隆值,而是在克隆关于如何访问这些值的指令。也许这就是您困惑的根源?

因此,Node* start 指向一个节点。 Node* traverse 指向相同的节点,正如您声明的那样 Node *traverser = start; 您可以通过 traverse->x 或 start->x 操作相关节点的值,并获得完全相同的结果。