【问题标题】:Is there a way I can combine these two methods?有没有办法可以结合这两种方法?
【发布时间】:2015-11-28 02:20:25
【问题描述】:

目前我正在创建一种在 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方法。有没有办法让它们成为一种方法而不改变我的 LinkedList 类的其他方面?

提前致谢!

【问题讨论】:

  • 直接调用reverse(head),将方法公开,这样就可以访问了。
  • 两种方法比较好。公共方法调用带有额外参数的私有递归方法是很常见的。
  • @YoungHobbit 我的主班无权访问头节点。
  • @PaulBoddington 真的,我从来不知道。我觉得有点奇怪。
  • @idude 那么这样就好了,没有什么问题。

标签: java methods data-structures linked-list overloading


【解决方案1】:

公共方法调用带有额外参数的私有递归方法是很常见的。有关此示例,请参阅 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 + " ");
}

【讨论】:

    【解决方案2】:

    从技术上讲,有一种方法,但我不推荐它。就是这样:

    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 对金钱的评论是正确的。

    【讨论】:

      【解决方案3】:

      Paul 给了我一个类似的答案,但我想我还是会发布我的,因为我认为您不想使用 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] + " ");
          }
      }
      

      【讨论】:

        【解决方案4】:

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

        在方法本身中,我们声明了一个 Node 变量,该变量的类型和名称与您的参数相同,以消除方法代码主体中的任何混淆,我们提供 default 为 0 (默认可以是任何你想要的)。然后我们检查新的 headerInfo[] 数组参数,看看是否提供了任何东西,如果有,我们将来自 headerInfo[] 数组的第一个元素的数据应用到(因为我们只为这个方法使用一个参数)新的节点类型变量 h。类中 ma​​in 方法的 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 打败了我 :)

        【讨论】:

          猜你喜欢
          • 2022-01-22
          • 1970-01-01
          • 1970-01-01
          • 2011-12-22
          • 2017-12-11
          • 1970-01-01
          • 2019-07-31
          • 1970-01-01
          • 2020-03-11
          相关资源
          最近更新 更多