【问题标题】:Java Linked List pointer confusionJava 链表指针混淆
【发布时间】:2017-12-13 05:31:11
【问题描述】:

以下代码来自 java LinkedList 实现。该方法在列表的索引点添加一个字符串元素,取自我的一本 cs 书籍。

链表类有2个全局私有变量

Node first;
Node last;


public void add(int index, String e) {
    if (index < 0 || index > size()) {
        String message = String.valueOf(index);
        throw new IndexOutOfBoundsException(message);
    }

    // Index is at least 0
    if (index == 0) {
        // New element goes at beginning
        first = new Node(e, first);
        System.out.println("ran");
        if (last == null)
            last = first;
        return;
    }

    // Set a reference pred to point to the node that
    // will be the predecessor of the new node
    Node pred = first;
    for (int k = 1; k <= index - 1; k++) {
        pred = pred.next;
    }

    // Splice in a node containing the new element
    pred.next = new Node(e, pred.next);
    System.out.println(toString());

    // Is there a new last element ?
    if (pred.next.next == null)
        System.out.println("ran");
        last = pred.next;
}

我的问题
我不明白Node first, last 在以下情况下如何更新

假设您有一个看起来像 ["1","2","3","7","4","5,"6"] 的列表

然后将元素“4”添加到索引 3

所以,列表看起来像["1","2","3","4","7","4","5,"6"],但是查看add方法的代码我不知道firstlast 节点指针得到更新。因为在我看来,这些是唯一运行的代码,因为索引不是 0 并且最后一个不会改变

编辑

对象节点first在toString方法(未显示)中用于遍历集合

    // Set a reference pred to point to the node that
    // will be the predecessor of the new node
    Node pred = first;
    for (int k = 1; k <= index - 1; k++) {
        pred = pred.next;
    }
    // Splice in a node containing the new element
    pred.next = new Node(e, pred.next);
    System.out.println(toString());

【问题讨论】:

  • 只是为了清楚我已经测试了这个添加方法并且它确实有效。

标签: java pointers linked-list


【解决方案1】:

添加前,第一个元素是“1”,最后一个元素是“6”。
添加后,第一个元素为“1”,最后一个元素为“6”。
firstlast 没有改变是对的——它们不需要改变,因为你没有改变第一个或最后一个元素。

【讨论】:

  • 好吧,我对此进行了测试,我用 10 个元素填充了列表,然后我将一个值添加到索引 6 并运行使用节点 first 遍历集合的 toString 方法.输出是正确的,但我不确定第一个节点对象是如何更新的。
【解决方案2】:

我认为您对这种链表实现的工作方式感到困惑。 firstlast 指针的存在只是为了跟踪列表的开始和结束。因此,当您在列表中间插入一个元素时,这些指针不会被更新,也不需要这样的更新。但是,如果插入位于列表的当前头部之前或当前尾部之后,它们确实会得到更新。这是处理头部插入的代码:

if (index == 0) {
    // New element goes at beginning
    first = new Node(e, first);
    System.out.println("ran");
    if (last == null)
        last = first;
    return;
}

这里的关键线实际上是这样的:

first = new Node(e, first);

first 指针被分配给一个新节点,该新节点又指向 first 节点。同样,如果一个新节点的插入出现在列表的末尾,下面的代码将处理它:

if (pred.next.next == null) {
    System.out.println("ran");
    last = pred.next;
}

这里将last 指针分配给插入last 之后的新节点。

但除了这两种边缘情况,没有必要用插入更新firstlast

【讨论】:

  • first 节点我认为是对列表中所有其他节点的引用,可用于生成 toString 方法,该方法在源代码的其他部分中执行,但该行没有 first = new Node(e,first);
  • I don't know how the first or last node pointers gets updated ... 据我所知,我已经回答了这个问题。如果您还想讨论为什么要维护 firstlast 指针,那么这可能是稍后的第二个问题。
【解决方案3】:

如果索引为0,则在beginnng中添加节点,for循环不起作用。 如果为 1,则不再执行循环,节点只是简单地添加到列表中。 但是,如果它是别的东西,那么直到到达 index-1 位置,循环将每个元素向后移动一步。然后循环外的代码(在包含新元素的节点中切片)在索引处插入元素。 如果循环执行后,索引是最后一个,则更新最后一个节点。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 2013-07-07
    • 2018-10-07
    • 1970-01-01
    • 2010-09-25
    • 2011-09-04
    相关资源
    最近更新 更多