保存/加载二叉搜索树的内容

时间:2014-04-11 14:46:23

标签: java binary-search-tree

所以我仔细研究了一些关于如何从二进制搜索树中获取元素并将它们写入文件的信息,然后将它们作为一种“加载”函数读回树中。我已经找到了一些人们去做的方法,但是我在实现这些建议时遇到了问题,例如在这里看到的,进入我的程序本身。所以我有几种排序方法,inOrder,postOrder和preOrder,但每次调用其中一个方法时都不一定需要写入文件。我想有一个saveFile和一个loadFile方法,它会在调用时自动写/读,但我是否必须在这些排序方法中调用writer / reader来获取BST中的每个节点?或者我可以有方法在外面做吗?它们不一定需要被分类到文件中,因为程序本身就会这样做。关于此事的一些建议是什么?

以下是我的一个排序类的示例(从单独的菜单类调用,为用户提供选择如何排序的选项:

public void inOrderTraverseTree (Node focusNode) {
    if (focusNode != null){
        inOrderTraverseTree(focusNode.leftChild);

        System.out.println(focusNode);

        inOrderTraverseTree(focusNode.rightChild);
    }//end if
}//end inOrderTraverseTree

它被调用的一个例子(来自菜单类,在交换机中):

case 1:
    tree.inOrderTraverseTree(tree.root);
    menu();
    break;

请让我知道建议!谢谢!

2 个答案:

答案 0 :(得分:1)

System.out.println写入标准输出,而不是文件。可以通过代码(您不应该这样做)或通过命令行将该输出重定向到文件,这很简单,使用管道(我认为Linux中的| > Windows中的1}},但确实有一些缺点。

另一种选择是将OutputStream传递给您的函数,如果您喜欢PrintStream方法,则可能是println

public void inOrderTraverseTree (Node focusNode, PrintStream printStream) {
    if (focusNode != null){
        inOrderTraverseTree(focusNode.leftChild, printStream);
        printStream.println(focusNode);
        inOrderTraverseTree(focusNode.rightChild, printStream);
    }//end if
}//end inOrderTraverseTree

要将其打印到文件,您可以使用:

inOrderTraverseTree(root, new PrintStream("fileName"));

请注意,new调用将在启动之前清除文件,因此您可能希望将PrintStream存储在临时变量中,将相同的对象传递给应写入的所有函数调用对它,或者您可以尝试使用OutputStream的构造函数。


另一种选择是将所有节点存储在LinkedList或类似的结构中,然后传递给函数(类似于上面的printStream的方式),然后你可以简单地遍历然后将节点写入文件。

public void inOrderTraverseTree (Node focusNode, LinkedList<Node> output) {
    if (focusNode != null){
        inOrderTraverseTree(focusNode.leftChild, output);
        output.add(focusNode);
        inOrderTraverseTree(focusNode.rightChild, output);
    }//end if
}//end inOrderTraverseTree

致电:

LinkedList<Node> output = new LinkedList<Node>();
inOrderTraverseTree(root, output);
// iterate through 'output' and write it to file

您可以返回LinkedList,而不是通过对代码进行一些更改来传递它。

这有点复杂,但确实为您的代码提供了更多模块化 - 如果遍历LinkedList的函数与文件I / O无关,则可能更好,但另一方面,您编写的代码可能不是您需要担心的规模(在代码大小和生命周期方面)(尽管您最终会在较大项目中执行您在较小项目中所做的工作) ,小型项目可能很快变大。

答案 1 :(得分:0)

如果我理解正确,您需要将树保存到文件,然后加载该树。你可以这样做。

  • 要保存树,请生成inorder遍历以及预订/后序并保存到文件
  • 要加载,请从文件中读取并使用两次遍历唯一地重建相同的树。(Example

您可以使用带有标志的相同遍历功能

public void inOrderTraverseTree (Node focusNode, boolean toSave) {
    if (focusNode != null){
        inOrderTraverseTree(focusNode.leftChild);            
        if(toSave)
           //write to file
        else
        System.out.println(focusNode);

        inOrderTraverseTree(focusNode.rightChild);
    }//end if
}//end inOrderTraverseTree