【问题标题】:How can I recursively invert a linked list with a void method?如何使用 void 方法递归地反转链表?
【发布时间】:2016-05-20 03:37:31
【问题描述】:

我无法使用 void 方法反转链表。我只允许使用两个指针节点(p,q)。我找到了几种方法,但不是一种无效的方法。我需要自己修改根列表(这就是为什么它必须是一个 void 方法)。该方法必须是递归的(我知道 void 方法中的基本定义不同)。这是我到目前为止所做的(不多)。

公共方法:

public void reverse(){
        reverse(first, null);
    }

私有方法:

private void reverse(Node p, Node q){
    if(p.next!=null)
        reverse(p.next,p);
    p.next=q;
}

【问题讨论】:

  • 所有你需要做的就是在到达末尾时更新列表的头部,它应该没问题。
  • 是的,我做到了。我仍然找不到有效的递归 void 方法。它们都返回修改后的列表。我需要它以便列表本身反转。
  • 为什么私有方法必须是void?我知道公共方法是void,因为它必须更新first 字段而不是返回任何内容,即更新列表的状态,但是为什么这意味着私有方法也必须是void
  • @Andreas 对。那么您是说我可以将私有方法设为 Node 方法而不是 void 方法,从而使用本文中的基本定义吗? link.

标签: java list recursion reverse


【解决方案1】:

您的代码运行良好!您可能只是没有正确测试它。以下是我的测试方法:

public static void main(String[] args) {
    Node last = new Node(4, null);
    Node first = new Node(1, new Node(2, new Node(3, last)));

    System.out.println("before: " + first);
    Node.reverse(first);
    System.out.println("after: " + last);
}

private static class Node {
    private int val;
    private Node next;
    public Node(int v, Node n) { val = v; next = n; }
    public String toString() { return val + (next == null ? "" : " -> " + next); }

    public static void reverse(Node first) {
        reverse(first, null);
    }
    private static void reverse(Node p, Node q) {
        if (p.next != null)
            reverse(p.next, p);
        p.next = q;
    }
}

输出

before: 1 -> 2 -> 3 -> 4
after: 4 -> 3 -> 2 -> 1

编辑:为避免在调用代码中需要last,添加一个方法getLast(),以便您的public reverse 可以在反向完成时返回它。由于 Java 只是按值传递,因此您无法从方法 reverse 内部更改调用者的 first 值。进行以下更改:

// in Node
private Node getLast() { return next == null ? this : next.getLast(); }
public static Node reverse(Node first) {
    Node last = first.getLast();
    reverse(first, null);
    return last;
}

// in main()
System.out.println("before: " + first);
first = Node.reverse(first); // update the value of first afterwards
System.out.println("after: " + first);

【讨论】:

  • 太棒了!我认为我走对了。但我仍然认为我需要在代码中的某个位置修改 first 值。这样它就可以以与您完全相同的方式编写,但不是打印System.out.println("after: " + last);,我可以打印System.out.println("after: " + first);在运行方法之后并且在修改列表之后。谢谢你:)
  • 我认为我的方法是这样的: 原文:1 -> 2 -> 3 -> 4 修改:1 last 节点,使其真正成为我的first 节点。
  • 我已经为我的答案添加了一个编辑,并提供了一个解决方案。看看你的想法:)
  • 太棒了。我认为这对我很有用!非常感谢兄弟。
猜你喜欢
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 2020-12-04
  • 2012-11-05
  • 1970-01-01
  • 1970-01-01
  • 2020-07-22
相关资源
最近更新 更多