我有一个LinkedList Node类:
Node list = new Node(5);
list.next = new Node(2);
list.next.next = new Node(3);
list.next.next.next = new Node(2);
list.next.next.next.next = new Node(1);
list.next.next.next.next.next = new Node(3);
printList(list);
deleteDups(list);
printList(list);
删除重复方法:
5, 2, 3, 2, 1, 3
5, 2, 3, 1
有效。但是怎么样?在方法中,我删除列表n,最后n为空。但为什么它不是空的:
public static void deleteDups(Node n) {
Hashtable<Integer, Boolean> table = new Hashtable<Integer, Boolean>();
Node previous = null;
while (n != null) {
if (table.containsKey(n.value)) previous.next = n.next;
else {
table.put(n.value, true);
previous = n;
}
n = n.next;
System.out.println("");
System.out.println("");
System.out.print("previous is ");
printList(previous);
System.out.print("n is ");
printList(n);
}
}
输出:
previous is 5, 2, 3, 2, 1, 3,
n is 2, 3, 2, 1, 3,
previous is 2, 3, 2, 1, 3,
n is 3, 2, 1, 3,
previous is 3, 2, 1, 3,
n is 2, 1, 3,
previous is 3, 1, 3,
n is 1, 3,
previous is 1, 3,
n is 3,
previous is 1,
n is
我错过了什么?
如果我打印n和上一个:
CREATE proc [dbo].[usp_InsertNewTransactionId](@transactionDate datetime2, @transactionId varchar(255))
as
begin
;with data as (select @transactionDate as transactionDate, @transactionId as transactionId)
merge transactions t
using data s
on s.transactionId = t.transactionId
when not matched by target
then insert ([date],transactionId) values (s.transactionDate, s.transactionId);
end
输出结果为:
*gtr
结束时n和前一个是空的!它是如何工作的?
答案 0 :(得分:3)
简单地说它迭代链表并记住它遇到的每个值。如果它遇到一个值,它已经看到它通过将前一个节点(在复制之前遇到的节点)与下一个节点(复制节点之后的那个节点)连接起来,中断了链中的重复条目。
想象一下,就像从链条中取出链接一样。
这整个算法就地工作,因此之后无需重新创建列表。你只需丢弃不再需要的节点。
这有点危险,因为仍然可以引用不再是过滤链表的一部分的节点。以某种方式使它们无效会更好。
另一方面,节点next
属性将始终导致已过滤链表的节点(在n步之后),如果算法尚未看到的列表中仍有值,或者{ {1}}如果重复节点已经在链表的末尾。尽管如此,null
节点仍然会有重复项,直到它再次到达重复自由链表的一部分节点,但是可以更改算法,以便即使这样也不会发生。
编辑以回答为什么printList最后没有打印/ next
:
这是因为此时n不再是您的起始节点,它始终是“下一个”节点。所以最后n实际上是“null”,因为“null”是最后一个节点之后的元素。你必须保留你的起始节点n(你传递给deleteDups方法的节点),因为这个节点描述了你过滤列表的起始节点。你的printList方法只打印你传递给它的节点之后的所有下一个节点。所以发生的最后一次调用是你的printList(前一个)(这包含最后一个元素)和printList(n)什么也不做,因为那时n是“null”。
尝试创建节点的链接列表。然后将第一个Node传递给deleteDups,然后使用传入它的Node调用printList。
null
答案 1 :(得分:0)
该列表已“重新创建”:previous.next = n.next;
更改节点,并使用此操作删除要跳过的项目
2 --> 3 --> 2
previous.next = n.next;
2 --------> 2