【问题标题】:Trouble with deleting nodes in Doubly Linked List删除双向链表中的节点时遇到问题
【发布时间】:2018-06-20 15:10:12
【问题描述】:

所以我正在构建自己的双向链表类(不是为了作业,只是尝试构建自己的库以供以后使用),并且在实现 removeAll 方法时遇到了一些困难。这是相关代码(如果您需要更多,请告诉我):

//ptr is a pointer node that moves through the list

//removes all nodes with type data
public void removeAll(T data) {
    while (findNode(data) != null) {
        deleteNode(findNode(data));
    } // end of while
} // end of removeAll method

//deletes single node
private void deleteNode(Node<T> del) {
    // del is head node 
    if (del.prevNode == null)
        removeFirst();
    // del is tail node
    else if (del.nextNode == null)
        removeLast();
    else {
        del.nextNode.prevNode = del.prevNode;
        del.prevNode.nextNode = del.nextNode;
        size--;
    } // end of if-else
} // end of deleteNode method

//returns node that matches criteria
private Node<T> findNode(T data) {
    ptr = head; // reset pointer
    while(ptr != null) {
        if(ptr.data == data)
            break;
        else {
            ptr = ptr.nextNode;
        } // end of if-else
    } // end of while
    return ptr;
} // end of findNode method

尝试删除 713 的输出(为简单起见,我使用整数):

[ 9 -6 -6 -6 -6 2 3 713 ] // this is just to show all elements in linked list
------------- // divider
[ 9 -6 -6 -6 -6 2 3 713 ]  // after trying to remove 713

我认为最有趣的是,如果我尝试删除所有 -6,removeAll 方法会起作用。

[ -6 9 -6 -6 -6 2 3 713 -6 ] //added -6 to beginning and end
-------------
[ 9 2 3 713 ] //all -6's gone

就好像 9 和 713 只是方法不起作用的随机情况。我认为问题在于 findNode 和 deleteNode 方法。测试 removeFirst 和 removeLast 方法表明它们可以完美地工作并提供正确的输出。非常感谢任何帮助/指导,我已经为此苦苦挣扎了将近 6 个小时。

【问题讨论】:

  • 你这样做是为了了解Java吗?否则:链表! - docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
  • 713是最后一个节点,你调用removeLast(),但是不显示那个方法的代码?除此之外,是什么让您认为构建自己的库比 java 提供的库更好?
  • 我不认为构建自己的链表以用于其他程序是一个好主意,但重新创建一个链表以进行编码练习是个好主意。
  • @JoshBrown 从您的输出中,显然,删除 713 不起作用。
  • 所以我做了一些测试,我发现它不会删除任何大于 127 或小于 -129 的数字。我认为这可能与将列表类型声明为 有关?如果我错了,请纠正我

标签: java data-structures linked-list doubly-linked-list


【解决方案1】:

问题在于这一行:

    if(ptr.data == data)

我想你的意思是:

    if (ptr.data.equals(data))

由于您无法在列表中存储ints,我假设您的元素类型是Integer。 Java 缓存Integer 对象用于经常使用的整数,例如-6,因此当您要求删除所有-6 时,您将获得对同样在列表中的缓存-6 对象的引用。然后与== 比较产生true,因为ptr.datedata 是对同一个对象的引用。删除有效。 713 没有被缓存,所以当你要求删除它时,你会得到一个 new Integer 对象。 ptr.datadata 是引用两个不同的相同对象。 == 产生 false。没有任何内容被删除。

PS 你不应该想在你的“自己的库中包含一个双向链表以供以后使用”。一方面,您永远不需要双向链表。预定义的ArrayListArrayDeque 在几乎所有情况下都将更好地服务于相同的目的。另一方面,使用标准库中的类的优势是巨大的。 20 多年来,这些类已被证明是可用的,并且您有人员为您维护它们。当您使用标准 API 时,您的代码的其他读者也会更容易理解。

链接: Question: Compare two objects with .equals() and == operator

【讨论】:

  • 您对Integer 类型的看法是正确的。你的解决方案确实有效。我完全忘记了 == 和 .equals() 之间的区别。感谢您的帮助/链接!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多