【问题标题】:how is the linked list actually being changed链表实际上是如何改变的
【发布时间】:2011-11-25 19:57:03
【问题描述】:

我想知道是否有人可以帮助我解决这个问题。我相信我大部分都了解代码和逻辑。我可以跟踪代码,这很有意义,但我不明白的一件事是.... LinkedListNode 之前的实际如何更改传入的 LinkedListNode n?

在我看来,该函数循环遍历 n,如果尚未找到该元素,则将其放入哈希表中。但是当它再次被发现时,它使用这个新创建的 LinkedListNode previous 跳过重复项并链接到下一个元素,即 n.next。 这实际上是如何断开 LinkedListNode n 的?似乎以前的 LinkedListNode 没有重复项,但是由于此函数中没有返回任何内容,因此 n 必须是更改的那个。我想我没有看到 n 实际上是如何改变的。

我们将非常感谢您提供清晰而彻底的帮助。谢谢=)

public static void deleteDups(LinkedListNode n){

    Hashtable table = new Hashtable();
    LinkedListNode previous = null;
    while(n != null){
        if(table.containsKey(n.data))
            previous.next = n.next
        else{
            table.put(n.data, true);
            previous = n;
        }
        n = n.next;
    }
}

行不行...

LinkedListNode previous = null;

创建一个新的 LinkedListNode?​​p>

所以这就是我如何做的逻辑...... 假设参数 n 传入为

5 -> 6 -> 5 -> 7

当代码第一次运行时,previous 为空。它进入了else语句,而previous现在是5?然后行 n = n.next 使 n 6?现在哈希表有 5 个,它再次循环并进入 else。 prev 现在是 6,hastable 有 6。然后 n 变为 5。它再次循环,但这次它进入 if,prev 现在是 7。n 将变为 7。我看到 prev 跳过了 5,但是.. .prev 如何取消链接 n?似乎 prev 是不包含重复项的 LinkedListNode

【问题讨论】:

  • "LinkedListNode 上一个 = null;" - 这不会创建新节点 - 这只是对节点的引用,而不是节点本身。

标签: java linked-list duplicates


【解决方案1】:

LinkedListNode 之前的实际如何改变 传入的LinkedListNode n?

看线

n = n.next;

这一行导致传递的节点 n 发生变化 - 每次迭代有效地将其向前移动一个节点。

它使用这个新创建的 LinkedListNode 之前跳过重复并链接到以下元素

不,这里没有新创建节点。节点previous始终指向现有LinkedList中的一个节点,其中传递的节点n是其中一个节点。 (可能是起始节点)。是什么让您认为它是创建的?

您似乎对节点和引用(以及整个 LinkedList)在 Java 中的工作方式的理解感到困惑。因为所有修改都发生在节点的数据上,而不是引用本身,(呃..那不完全正确),传递给方法的原始 LinkedList 在方法返回后确实得到了修改。您将需要详细分析 LinkedList 结构和工作原理,以了解其工作原理。我建议首先弄清楚 Java 中的值传递和引用传递是什么。

编辑:

您对运行的分析是正确的,但是您的困惑仍然存在,因为您对某些事情在概念上并不清楚。

在分析结束时,您问“..prev 是如何取消链接 n 的?看起来 prev 是不包含重复项的 LinkedListNode

这是一团糟——首先,您需要区分 LinkedListNodeLinkedList 本身。 prevnLinkedListNode 的两个实例,而不是 LinkedList 本身。在您的示例中,LinkedList 未命名(我们没有名称来引用它)。这是原始列​​表 - 没有其他列表。

其次,在您的插图中,您显示的数字只是节点的一部分,称为节点数据。您错过的另一部分是每个节点中隐含的next LinkedListNode 引用。您绘制的链接 -> 实际上是每个节点中的下一个引用。当您说 prev 跳过 5 时,实际发生的是具有数据 6 的节点的下一个指向具有数据 7 的节点。

开始时: 5|next -> 6|next -> 5|next -> 7|next->NULL

跳过 5 后: 5|next -> 6|next -> 7|next->NULL

如您所见,链表已更改!使用 prev 或 n 更改都没有关系,更改保留在列表中。

【讨论】:

  • 哦,我在问题中添加了 cmets。我想我有点理解你的意思。这是按引用传递/按值传递的问题吗?似乎您可以在之前创建一个新的 LinkedListNode 并让它指向 n 指向的位置。因此,由于previous = n,prev现在等于n,并且由于prev跳过了一个元素,它也改变了n指向的位置,因为我们将n设置为等于previous?它是否正确?对困惑感到抱歉。但非常感谢您的帮助!
  • @Crystal,请看我的编辑。不,您对 prev 和 n 工作方式的理解不正确!完成编辑并详细考虑。
  • 哦,我明白了,我想我明白了。所有的 LinkedListNode 都指向同一个 LinkedList,它在函数中没有命名或给出。写 LinkedListNode previous = null 只是引用一个 LinkedListNode 节点对象,它与 LinkedListNode n 在同一个链表中。从函数后面的赋值来看,previous 和 n 都是链表的实际节点对象(即,它们组成链表)。并且 2 个对象正在操作链接列表,因为它们是列表的实例。对吗?
  • 大部分是的,除了最后一位......“因为它们是列表的实例” - 不 - 它们是 LinkedListNode 的实例,因为它们将节点引用到同一个 LinkedList 中。跨度>
【解决方案2】:
if(table.containsKey(n.data))
            previous.next = n.next

是进行删除的部分。它将先前节点的next 字段的引用分配给当前节点之后 的节点,实际上取消了当前节点的链接。

【讨论】:

    猜你喜欢
    • 2011-10-27
    • 1970-01-01
    • 2011-06-21
    • 2012-05-18
    • 2019-09-10
    • 1970-01-01
    • 2016-07-10
    • 2015-04-29
    相关资源
    最近更新 更多