【问题标题】:How to rotate Binary Tree recursion given a null stopper如何在给定空终止符的情况下旋转二叉树递归
【发布时间】:2015-06-11 01:29:55
【问题描述】:

我正在从文件中读取字符串,并在节点的子节点为空时记录了“~”。然后我将这些字符串添加到二叉树中。但是我的代码只是将所有字符串(包括“~”)添加到左树节点中。

如何让算法在到达“~”时停止添加左节点并插入右节点(当然,除非下一个字符串也是“~”)?

这是我的代码:

// Reads the elements in the tree in pre-order
public void fromFile()
{
   BufferedReader in;
   String s = null;
   try {
        in = new BufferedReader(new FileReader("animal_game.txt"));
        StringBuffer stringBuffer = new StringBuffer();
        while( (s=in.readLine()) != null )
        {

            stringBuffer.append(s);
            stringBuffer.append("\n");

        }

        fromFile(stringBuffer.toString());


        in.close();
   } 
   catch (IOException ex) 
   {
           Logger.getLogger(Tree.class.getName()).log(Level.SEVERE, null, ex);
   } 

}

public void fromFile(String s)
{
    if (root == null)
    {
        root = new Node<>((T)s);
        size++;
    } 
    else 
    {
        fromFile(root, s);   
    }
}

// helper function
private void fromFile( Node<T> node, String s) 
{
        // if null tree node reached, 
        if(s==NULL_TREE_NODE)
        {
            fromFile(node, s);
        }

        // insert left node
        if (node.no == null) 
        {
            node.no = new Node<>((T)s);
        } 
        else 
        {
            fromFile(node.no, s);
        }

        // insert right node
        if (node.yes == null) 
        {
            node.yes = new Node<>((T)s);
        } 
        else{
            fromFile(node.yes, s);
        }
}

这是我将树保存到文件的代码:

// Writes the elements in the tree in pre-order
public void toFile()
{
    // Writes in preorder starting with the root node
    if (root != null) 
    {
        BufferedWriter out;
        try {
            out = new BufferedWriter(new FileWriter("animal_game.txt"));
            toFile(out, root);
            out.close();
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(Tree.class.getName()).log(Level.SEVERE, null, ex);
        } 
    }
}

// Helper function
private void toFile(BufferedWriter out, Node<T> node) 
{
    try {

        if (node == null) {
        out.write(NULL_TREE_NODE); // null
        out.newLine();
        return;
    }
    //assert !node.data.equals(NULL_TREE_NODE); // Reserver for us..
    out.write((String)node.data); // these nodes hold Strings
    out.newLine();
    toFile(out, node.no);
    toFile(out, node.yes);

    } 
    catch (IOException ex) 
    {
        Logger.getLogger(Tree.class.getName()).log(Level.SEVERE, null, ex);
    }

}

这是我的文件


它是哺乳动物吗?

它是爬行动物吗?

是鱼吗?

鹈鹕

~

~

鲨鱼

~

~

它灭绝了吗?

乌龟

~

~

迅猛龙

~

~

它有毛吗?

大象

~

~

【问题讨论】:

  • 你能给我们整个文件吗?这个过程的总体目标是什么?目前,似乎 fromFile(Node, String) 将始终终止而不实际向节点添加任何信息,除非 s== NULL_TREE_NODE 在这种情况下它只会调用自身导致堆栈溢出?另外,您是否打算在那里使用 == 来表示字符串相等?
  • 这是我的 Tree 类中的一个函数。我主要用 treename.fromFile(); 调用它
  • 但这会创建一个包含所有左节点的树,包括“~”字符
  • 在 s==NULL_TREE_NODE 的情况下我将如何调用它的父节点?
  • 我的意思是你能告诉我们整个 Tree 类。我认为它正在生成所有左节点,因为它首先检查 node.no (左)是否为空。我仍然看不到字符串数据是如何进入树的。首先将所有对象放在一个字符串中是个好主意吗?用换行符分隔 List 是否更有意义? (您已经拥有读者提供的信息)。当到达一个空树节点时,您不应该“调用父节点”,而是返回,因为如果结构正确,您最初是从父节点调用的。

标签: java binary-search-tree


【解决方案1】:

你应该改变你的 fromFile() 来匹配你的 toFile():而不是接受一个节点和一个代表整个文件的字符串,取一个 BufferedReader,让它可以轻松地读取单个行。此外,将帮助程序构建函数更改为返回一个节点,以便它可以在 ~ 节点的情况下返回 null。 然后,可以递归地构建整个树,当到达 ~ 节点时返回 null 备份树:

 private Node<T> fromFile(BufferedReader s) throws IOException
    {

            String line = s.readLine();
            if(line == null) throw new IllegalArgumentException("File does not specify complete tree");
            // if null tree node reached, 
            if(line.equals(NULL_TREE_NODE)) return null;
            Node<T> node = new Node<>();
            node.data = line;
            node.no = fromFile(s);
            node.yes = fromFile(s);
            return node;
    }

然后,稍微调整一下 fromFile():

public void fromFile()
{
   try(BufferedReader in = new BufferedReader(new FileReader("animal_game.txt"))) 
   {
        root = fromFile(in);
   } 
   catch (IOException ex) 
   {
           Logger.getLogger(Tree.class.getName()).log(Level.SEVERE, null, ex);
   } 

}

我还修改了它以使用 try-with-resources 语句,以方便使用,并保证在异常时正确释放资源。见http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-08
    • 2016-08-15
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多