【问题标题】:How a LinkedList Keeps Track of All Nodes - C#?LinkedList 如何跟踪所有节点 - C#?
【发布时间】:2019-01-13 00:05:57
【问题描述】:

我一直在努力开发自己的单链表,我不明白如何将节点插入到链表的末尾?

代码如下:

class LinkedList
{
    private Node head;

    public void AddLast(int value)
    {
        if (head == null)
        {
            head = new Node();

            head.value = value;
            head.next = null;
        }
        else
        {
            Node temp = new Node();
            temp.value = value;

            Node current = head;

            while (current.next != null)
            {
                current = current.next;
            }

            current.next = temp;
        }
    }

    public void PrintAll() 
    {
        Node current = head;

        while (current != null)
        {
            Console.WriteLine(current.value);
            current = current.next;
        }

    }
}

这里是主要方法

    static void Main(string[] args)
    {
        LinkedList list = new LinkedList();
        list.AddLast(3);
        list.AddLast(5);
        list.AddLast(4);
    }

1) 我完全得到了第一部分 list.AddLast(3)。由于 head 为空,我们创建一个新节点 head 并为其赋值。

2) 当调用 list.AddLast(5) 时,head 不再为 null,因此我们创建了一个新的临时节点,并为其赋值。现在我们创建一个新的节点 current 保存 Head 的值,要注意 Head.Next 为空。

现在我们遍历 current 并将我们的 temp 节点放置到 current.Next。

3) 现在,在调用 list.AddLast(5) 时,当前不应该再次被 Head 的内容覆盖吗?这是 Head.Value = 3 和 Head.Next = Null。

那么不应该是 current.Value = 3 和 Current.Next = Null 吗?如果不是,那为什么?

【问题讨论】:

  • 使用 BCL LinkedList<T>,您不必担心
  • 这也有效,但我不明白为什么,我正在学习自己制作。

标签: c# .net data-structures linked-list singly-linked-list


【解决方案1】:

链表有很多实现。然而对于一个简单的单链表,我们是这样认为的

如果我理解正确,这是你不理解的部分

// All this part of the method does is add the new value to the end of the list

// create node
Node temp = new Node();
// assign its value
temp.value = value;

// now we want to start with the head and follow 
// the chain until we find the last node
Node current = head;
// has it got a next element
while (current.next != null)
{
    // if so change current to next and look again
    current = current.next;
}

// yay no more nexts, lets add temp here
current.next = temp;

// you have effectively added your new element to the end of the list

说到另一个常见的实现是将Last/Current 节点保存在类中(就像你对head 所做的那样)。

在这种情况下,我们可以引用该 Node 并添加到其下一个节点并更新类中的 Last 引用,而不是遍历链。但是,当我们必须删除最后一项时,我们不仅要记住课堂上的null Last,还要记住null 它的父母Next 的引用。

做到这一点的唯一方法是再次迭代链。

为了更容易,我们可以实现一个双向链表,以便更容易找到它的父级

更新

我不明白的是为什么到下一个节点的链接没有丢失 当当前持有该信息的人每次更新内容时 头。

在上面,把current看作一个临时变量,它在生活中唯一的工作就像是链条中下一个环节的临时标记,

当我们调用它时

current = current.next;

它所做的一切都是抓取current.next 中的内容,并再次抓住它等待循环条件。我们可以在不破坏 current.next 中的内容的情况下调用它

最后一次,当我们在current.next 中什么都没有找到的时候 即当循环检查 current.next== null 我们可以安全地将临时节点放入其中 current.next = temp;

【讨论】:

  • 非常感谢TheGeneral的解释,我不明白的是,当当前持有该信息的人每次都使用Head的内容更新时,为什么指向下一个节点的链接不会丢失。
【解决方案2】:
Node current = head;

当上述语句执行时,current 暂时只分配了head 的引用而不是值。所以current在那一刻只指向head。如果在此语句之后执行,current.value 将为您提供 head 的值。

while (current.next != null)
{
    current = current.next;
}

现在,当上面的while循环执行时,它遍历链表并将当前节点带到链表中的最后一个节点,该节点将具有current.next = null

current.next = temp;

当上述语句执行时,新节点被添加到链表的最后。

【讨论】:

  • 所以它只指向那个?但是电流的变化会影响头部吗?你说的不是和这个差不多吗?整数 a = 2;诠释 b = a; b = 4; Console.WriteLine(a);但是这里 a 的值保持不变 //2
  • 您已经给出了值类型变量的示例,但current 我相信是引用类型变量。在值类型的情况下,实际值存储在变量本身中。在引用类型变量的情况下,该变量不包含实际值,而是指向存在实际值的内存位置的地址。所以current = head 没有将current 的实际值设置为head 的值。而是将current中存储的内存地址更改为head中存储的内存地址
  • 非常感谢,类是引用类型,结构是值类型,完全忘记了它们。非常感谢。
【解决方案3】:

您创建LinkedList 的新实例。

list.AddLast(3); --> headnull,你创建一个新的Node 并将其分配给head

list.AddLast(5); --> 创建一个新的Node temp 并将5 分配给该值。请记住headvalue = 3nextnull。创建了一个名为current 的新变量,它指向head。然后while 遍历树,如果currentnext 不为空,则将currentnext 重新分配给那个node。在这种情况下,while 循环不会运行,因为headnext 为空,所以它所做的只是将head.next 分配给您的current 节点。此时我们有head.value = 3head.next = new Node(5, null);

list.AddLast(4); --> 与上面相同,但 while 循环现在运行。它一路遍历找到一个没有next 值的Node,并将4 分配给它。此时我们有head.value = 3, head.next = new Node(5, new Node(4, null))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 2020-03-20
    • 1970-01-01
    • 2013-03-02
    • 2023-01-30
    相关资源
    最近更新 更多