二叉树/递归(Java)(更新)

时间:2016-04-04 14:18:13

标签: java recursion tree

(更新)

我的课程一直致力于使用递归来创建像河内的塔,斐波纳契以及所有有趣的东西。问题是,我并不是很了解一切。我理解递归的一般概念,但在制作程序时将其付诸实践对我来说感觉很复杂。我知道它一遍又一遍地调用这个方法,通常会在它退出的情况下达到一个基本情况,但是我很难编写能够做我想做的事情的代码。

我们正在研究二叉树。我们应该使用我教授提供的一些代码来分割树,然后编写一个递归方法来打印出树所包含的所有路径。我们的输入将类似(a(b()())(c()())),它将是一棵树:

 a
b c

b和c下面会有0个孩子。 (a)是一个可能的节点,()将是一个空节点,它将是该路径的结尾。我们的目标是打印出所有路径,因此对于我的示例,输出将是:

a b

a c

我们给出的代码包含一个帮助器方法,我们可以用它来编写递归方法:

public class BinaryTree {


public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    String tree = scan.nextLine();//correct format : (a()())
    String[] t = splitTree(tree);
    System.out.println(Arrays.toString(t));

}
public static String[] splitTree(String tree)
{
    //expected format
    //(node tree tree)
    //0 1 2-x x-(length-2) length-1
    if(tree.length() <= 2)//tree not long enough to process
        return new String[]{tree};

    String[] temp = new String[3];
    temp[0] = "" + tree.charAt(1);//grab tree node
    tree = tree.substring(2, tree.length()-1);//remove node and outer paren
    int parenCount = 0;//count of open paren
    int endTreeOne = 0;//end of first tree
    for(int i = 0; i < tree.length(); i++)
    {
        if(tree.charAt(i) == '(')
            parenCount++;
        if(tree.charAt(i) == ')')
            parenCount--;
        if(parenCount == 0)
        {
            endTreeOne = i;
            break;//ends for loop early
        }
    }
    temp[1] = tree.substring(0, endTreeOne+1);//left tree
    temp[2] = tree.substring(endTreeOne+1);//right tree
    return temp;
}

此方法基本上会转换(a(b()())(c()()))之类的字符串,并使它们成为[a, (b()()), (c()())]。基本上拆分树。

我真的不确定如何从这里开始编写我的递归方法。我觉得自己很丢失(结果很沮丧)。我想我需要让我的方法检查是否存在“()”,那么这就是路径的结束。这是退出我需要的循环的基本情况吗?我不知道如何指定树的哪一侧也可以。如果有人可以提供任何帮助,提示或让我按照正确的思路解决这个问题,我将非常感激。

到目前为止,我真的只是(除了上面提供的辅助方法):

static ArrayList<String> path = new ArrayList<>();
public static String treePaths(String s)
{

        String[] split = splitTree(s);
        if(split[1].equals("()") && split[2].equals("()"))
        {
            path.add(split[0].toString());
            System.out.println(path.toString());
            return split[0];
        }
        else
        {
            String s2 = "";
            for(int i = 0; i < split.length-1; i++)
                {
                s2 = split[i].toString();
                }
                path.add(split[0].toString());
                return treePaths(s2);

        }

我的递归方法,我很确定它已经错了。如果有人可以提供任何帮助(特别是使用我教授提供的代码),我将非常感激(即使它只是指向我正确的方向或帮助我更好地理解我需要做什么。有人在此之前帮助了我在这里,但我不确定它是否以我需要的方式完成。

2 个答案:

答案 0 :(得分:1)

你很亲密。您的退出条件的提示在辅助方法的开头给出。如果输入的长度为2个字符或更少,则返回包含输入的1个大小的数组。它发生了,一个空节点会触发这个if语句。

答案 1 :(得分:1)

好吧,我正在写一个新的答案,因为最后一个是不正确的。 我已经解决了这个问题(至少是原来只涉及打印路径的问题)。

你是对的,你应该从递归方法的退出条件开始 什么是退出条件?它应该是当你到达一条路径的尽头。然后你退出并上升方法调用堆栈 查看您提供的示例解决方案,路径末端出现在一个元素中,该元素具有两个空元素作为子元素,如示例中的元素b和c。 当你给它时,helper方法给你一个独特的输出&#34;一个有两个空元素的元素&#34;

4月5日继续:
退出条件是

if (split[1].equals("()") && split[2].equals("()"))

在这种情况下,您有一个路径结束,路径由递归方法堆栈保存 例如:for path a b c
第一次致电treePaths()时遇到a,并且遇到了treePaths()遇到b,并且遇到了treePaths()并称其为c并将其识别为结束-of路径。
现在需要做什么才能使这种情况发生?这如何塑造传递给每个方法的输入?