[英]Reversing a singly linked, sentinel based, list recursively (works, but not in the way I'd like it to)
我正在准备面试,并编写了此简单功能以递归地反转单个链接列表。 第一个节点是前哨节点head
。 以下代码适用于: list.reverse(list.head.next)
,但是如果我只是将其传递给head
则似乎无法使其正常工作。
public Node<T> reverse(Node<T> current)
{
if (current == null)
return head;
if (current.next == null)
{
head.next = current;
return current;
}
reverse(current.next).next = current;
current.next = null;
return current;
}
我认为当我将其传递给head
而不是head.next
时它head.next
因为我说current.next = null
,但是即使我检查current == head
还是current.data == null
且仅使用current.next = null
如果这些都不是,则仍然无效。 我敢肯定有一个非常简单的修复程序,但是我现在还没有看到。
上面的如果通过的head
将返回一个空列表,并且如果进行了建议的更改,只是无法完成运行,但是我没有得到任何错误。
(编辑)我现在可以解决您的问题:
简单来说,前哨头只是充当指向第一个节点的指针,而不是链表的一部分。 因此,它不会参与反向过程,并且需要单独处理。
这意味着原始列表如下所示:
HEAD -> a -> b -> c -> null
反向后,它看起来应该像
HEAD -> c -> b -> a -> null
简而言之,它看起来应该像(假设传入head.next时您的代码已经可以使用)
public Node<T> reverse(Node<T> current)
{
if (current == head) {
return reverse(current.next);
}
// rest of your original code.
}
只是进一步建议:
作为列表类的公共实例方法,您的reverse()方法不应接受当前节点,因为从概念上讲,它对于调用者而言毫无意义。
我相信您应该对此方法进行保护,这意味着:
public void reverse() {
this.head = reverseInternal(head);
}
private Node<T> reverseInternal(Node<T> node) {
// your original reverse logic
}
有了这种封装,当您传递哨兵头时,您甚至无需reverseInternal(head.next)
去使逆向工作:您可以在公共的reverse()
方法中简单地调用reverseInternal(head.next)
。
第一:如果返回空列表,则“不起作用”。
头不必为空节点。 通常,您应该仅将第一个节点(在您的情况下为list.head.next
) list.head.next
为list.head
。 head
应该是列表开始的引用,而不是单独的节点。
当您将代码传递给list.head
时,您的代码清空列表的原因是它将list.head.next
设置为null。 这是因为您假定传递到列表的节点是常规节点,而头节点是特殊节点。
这是您的假设的解决方案(我假设有人坚持使用这种奇怪的超脱头法。如果您自己设计列表,请不要这样做。请...)
public Node<T> reverse(Node<T> current)
{
if (current == null)
return head;
if (current.next == null)
{
head.next = current;
return current;
}
Node<T> temp = current.next;
current.next = null;
head.next = temp;
reverse(temp).next = current;
return current;
}
说明:这仍然将最后一个节点的下一个设置为null
,但是在列表中遍历列表时,将列表的头部向下推了一个点,最终将其指向最后一个(现在是第一个)成员。
这有点功课。
但是还是。
一般来说:
f(Node<T> current, ...) {
f(current.next, ...);
}
对于列表a > b > c > d > e
端坐在midle d
,一个可能已经建成c > b > a
不已,所以你猜怎样,需要作为附加参数f
?
祝好运。
评论后:
public Node<T> reverse(Node<T> current)
{
return reverseRec(current, null);
}
/**
* @param current to-do (sub-)list.
* @param resultDone done reversed list sofar.
* @return reversed result.
*/
public Node<T> reverseRecursively(Node<T> current, Node<T> resultDone)
{
if (current == null) {
return resultDone;
}
Node<T> next = current.next;
current.next = resultDone;
return reverseRecursively(next, current);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.