有没有一种方法可以将这两种方法结合起来?

4

我正在创建一个用Java翻转链表的方法,但需要两种方法:

public void reverse(){
    reverse(head);
}

private void reverse(Node h){
    if(h.next==null){
        System.out.print(h.data+" ");
        return;
    }

    reverse(h.next);
    System.out.print(h.data+" ");   
}

这样,我使用0个参数调用了reverse方法,然后该方法调用了另一个reverse方法。有没有办法将它们合并为1个方法,而不改变LinkedList类的其他方面?
提前致谢!

直接调用 reverse(head) 方法,将其设置为公共方法,这样它就可以被访问到了。 - YoungHobbit
3
两种方法更好。公共方法调用带有额外参数的私有递归方法很常见。 - Paul Boddington
@YoungHobbit,我的主类无法访问头节点。 - idude
@PaulBoddington 真的吗,我从来不知道。这对我来说有点奇怪。 - idude
@idude 那就这样吧,没有任何问题。 - YoungHobbit
4个回答

5

在公共方法中调用带有额外参数的私有递归方法是非常常见的。可以查看Arrays.deepToString(Object[])的源代码来了解示例。

然而,在您的情况下,完全避免使用递归可能更好。递归的一个问题是,您只能在嵌套方法调用到一定深度之前才能得到StackOverflowError

另一种选择是使用循环代替。以下代码将起作用:

public void reverse(){
    List<Node> nodes = new ArrayList<>();
    for (Node n = head; n != null; n = n.next)
        nodes.add(n);
    for (int i = nodes.size() - 1; i >= 0; i--)
        System.out.print(nodes.get(i).data + " ");
}

3

从技术上讲,有一种方法可以实现,但我不建议这样做。具体方法如下:

public void reverse( Node... nodes )
{
    Node h;
    if( nodes.length == 0 )
        h = head;
    else
    {
        assert nodes.length == 1;
        h = nodes[0];
    }

    if( h.next == null )
    {
        System.out.print( h.data + " " );
        return;
    }

    reverse( h.next );
    System.out.print( h.data + " " );   
}

请注意,这也需要将类Node公开,这也不是一个好主意。 (或者你可能只会因为有一个接受私有类型参数的公共方法而收到警告,然后你可以抑制它;我不记得了。)
但是Paul Boddington的评论非常准确。

2

保罗已经给出了类似的答案,但我认为我还是要发布我的答案,因为我假设您不想使用ArrayList作为依赖项:

是的,这是可能的。如果它是一个双向链表,您可以遍历该列表到达最后一个节点,然后沿着列表向前走。但是,我还将假设它是一个单向链表,因此我将使用数组来存储所有节点引用来回答。此外,我假设您有另一种方法来计算长度。

public void reverse() {
    int length = length();
    Node [] nodes = new Node[length];
    Node currentNode = head;

    int i = 0;
    // Populate the array
    while(currentNode != null)
    {
        nodes[i] = currentNode;
        currentNode = currentNode.next;
        i++;
    }

    // Iterate backwards to print the array
    for(int j = length -1; j >= 0; j--)
    {
        System.out.println(nodes[i] + " ");
    }
}

1

是的。您可以将显示的第二个方法中的参数“act”设置为可选参数。在下面的方法声明中,我们本质上使节点类型参数成为可以传递为空的节点数组。由于我们只需要向我们的方法传递1个参数,因此我们只需要包含在数组的元素索引0(数组的第一个元素)中的提供的节点数据。

在方法本身内部,我们声明了一个节点变量,其类型和名称与您的参数相同,以消除方法代码主体中的任何混淆,并提供默认值0(默认值可以是任何您想要的)。然后,我们检查新的headerInfo []数组参数是否有任何提供的内容,如果有,则将来自headerInfo []数组的第一个元素(因为我们仅针对此方法使用一个参数)的数据应用于新的节点类型变量h。类中的main方法的args []参数执行相同的操作。

public void reverse(Node... headerInfo){
    Node h = 0;
    if (headerinfo.length != 0) { h = headerInfo[0]; } 

    if(h.next==null){
        System.out.print(h.data+" ");
        return;
    }

    reverse(h.next);
    System.out.print(h.data+" ");   
}

现在这个方法可以被称为reverse()或者reverse(head)。
编辑:
哎呀...Mike比我快 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接