Java中的反向LinkedList
我正在这篇文章中寻找解决方案 我复制了下面的一个解决方案。我已经实现了它,效果很好Java中的反向LinkedList,java,collections,Java,Collections,我正在这篇文章中寻找解决方案 我复制了下面的一个解决方案。我已经实现了它,效果很好 public ListNode Reverse(ListNode list) { if (list == null) return null; // first question if (list.next == null) return list; // second question // third question - in Lisp this is easy, but we
public ListNode Reverse(ListNode list)
{
if (list == null) return null; // first question
if (list.next == null) return list; // second question
// third question - in Lisp this is easy, but we don't have cons
// so we grab the second element (which will be the last after we reverse it)
ListNode secondElem = list.next;
// bug fix - need to unlink list from the rest or you will get a cycle
list.next = null;
// then we reverse everything from the second element on
ListNode reverseRest = Reverse(secondElem);
// then we join the two lists
secondElem.Next = list;
return reverseRest;
}
然而,我不明白的是最后几行
secondElem.next = list;
return reverseRest;
看来我们根本就不退第二个元素了?但是我调试了代码,看起来secondElem已经在reverseRest中了。这是因为它在Java中是按值引用的,并且在应用
secondElem.Next=list
时会自动更新吗?如果您的目标是简单地反转列表,请使用不要考虑传递语义,请考虑内存中的对象和包含对它们的引用的变量
初始状态:
(list)
|
V
[ 1 ] -> [ 2 ] -> ... -> [ N ]
(list) (secondElem)
| |
V V
[ 1 ] [ 2 ] -> ... -> [ N ]
(list) (secondElem) (reverseRest)
| | |
V V V
[ 1 ] [ 2 ] <- ... <- [ N ]
(list) (secondElem) (reverseRest)
| | |
V V V
[ 1 ] <- [ 2 ] <- ... <- [ N ]
list.next=null后的代码>:
(list)
|
V
[ 1 ] -> [ 2 ] -> ... -> [ N ]
(list) (secondElem)
| |
V V
[ 1 ] [ 2 ] -> ... -> [ N ]
(list) (secondElem) (reverseRest)
| | |
V V V
[ 1 ] [ 2 ] <- ... <- [ N ]
(list) (secondElem) (reverseRest)
| | |
V V V
[ 1 ] <- [ 2 ] <- ... <- [ N ]
递归调用后:
(list)
|
V
[ 1 ] -> [ 2 ] -> ... -> [ N ]
(list) (secondElem)
| |
V V
[ 1 ] [ 2 ] -> ... -> [ N ]
(list) (secondElem) (reverseRest)
| | |
V V V
[ 1 ] [ 2 ] <- ... <- [ N ]
(list) (secondElem) (reverseRest)
| | |
V V V
[ 1 ] <- [ 2 ] <- ... <- [ N ]
然而,我不明白的是最后几行
secondElem.next = list;
return reverseRest;
secondElem.next=列表
返回反向测试
让我逐一向您解释您不理解的两行内容:
1.secondElem.next = list;
我认为secondElem的创建增加了复杂性。根本不需要变量secondElem
与此相反:
// then we reverse everything from the second element on
ListNode reverseRest = Reverse(secondElem);
// then we join the two lists
secondElem.Next = list;
使用以下命令:
ListNode reverseRest = Reverse(list.next);
list.next.next = list;
它更容易掌握。最后一行代码清楚地显示了列表反转过程本身
2. return reverseRest;
查看reverseRest变量的用法并理解其用途。它的唯一目的是将列表的原始尾部的值过滤到所有递归调用的末尾,这样我们就可以将原始尾部(也是新的头部)返回给调用反向函数的主函数。您必须理解,在递归调用之间,我们根本没有更改变量reversereest的值——无论我们从Reverse(secondElem)收到什么作为返回值,我们都是从函数返回“原样”的值,从而快速实现这一点 更好的方法是使用DegendingIterator()
。这取决于他是想“永久”反转列表,还是只想以相反的顺序进行迭代。