使用Java从txt文件创建树

时间:2014-06-11 14:02:46

标签: java data-structures tree

我应该使用以下类在Java中实现树数据结构:

public class Tree<T extends Comparable<T>>
{
    private TreeNode<T> root;

    public Tree(TreeNode<T> root)
    {
        this.root = root;
    }

    public void findChild(T data) { ... }
    public void findSibling(T data){ ... }
    public void printProgeny() { .. }
    public static Tree<String> createProgeny(String file) { ... }

    ...
}



public class TreeNode<T extends Comparable <T>>
{
    public T data;
    public TreeNode<T> parent;
    public TreeNode<T> leftChild;
    public TreeNode<T> rightSibling;

    ...
}

然后通过读取如下所示的txt文件来测试它:

Adam Jacob Hannah Sarah
Hannah Esther Abel
Abel David

其中一行中的第一个字符串是以下字符串的父字符串。 这就是我在努力的地方。

假设我分开了第一行,所以我有一个[Adam,Jacob,Hannah,Sarah]的数组。如何使用给定的方法从中创建子树?

我认为一旦我知道如何创建树并正确设置指针,其他方法就不会那么难实现

感谢任何帮助

编辑: 树看起来像这样

      Adam
  /    |    \
Jacob Hannah Sarah 
      /    \
    Esther  Abel
             |
            David

......或在Knuth变换之后:

    Adam
   /
 Jacob
    \
   Hannah
    /    \
 Esther  Sarah
     \
    Abel
    /
  David

3 个答案:

答案 0 :(得分:0)

您可以创建一个带有<T extends Comparable<T>> TreeNode<T> makeTree(T[] data)签名的递归函数,方法是:

  1. 创建新的TreeNode以返回
  2. 将节点的data设置为数组中的第一个元素。
  3. 将其余元素拆分为兄弟和子组
  4. 调用两个子组中的makeTree()功能,前提是它们不是空的
  5. 在原始节点上,将子节点和兄弟节点设置为返回的节点
  6. 将返回的节点的父节点设置为原始节点。
  7. 最后返回原始节点。

答案 1 :(得分:0)

您可以使用Map<String, TreeNode<String>>存储已创建的节点:

BufferedReader br = //.. this is your file reader

Map<String, TreeNode<String>> stringToTreeNode = new HashMap<>();
TreeNode<String> root = null;
String line;

while ((line = br.readLine()) != null) {
    String[] lineParts = line.split(" ");
    int oldSize = stringToTreeNode.size();
    TreeNode<String> parent = getOrCreateTreeNode(stringToTreeNode, lineParts[0]);
    if (oldSize != stringToTreeNode.size()) {
         // new parent node created

         // in the end the root is the only node without a parent
         root = parent;
    }
    if (lineParts.length > 1) {
        // create children
        TreeNode<String> child = getOrCreateTreeNode(stringToTreeNode, lineParts[1]);
        parent.leftChild = child;
        child.parent = parent; 
        for (int i = 2; i < lineParts.length; i++) {
            TreeNode<String> nextChild = getOrCreateTreeNode(stringToTreeNode, lineParts[i]);
            nextChild.parent = parent;
            child.rightSibling = nextChild;
            child = nextChild;
        }
    }
}
Tree<String> result = new Tree<String>(root);

将此作为辅助功能使用:

static TreeNode<String> getOrCreateTreeNode(Map<String, TreeNode<String>> map, String key) {
    TreeNode<String> result= map.get(key);
    if (result== null) {
         result = new TreeNode<>();
         result.data = key;
         map.put(key, result);
    }
    return result;
}

答案 2 :(得分:0)

您的方法返回void是不寻常的。我只能假设findChild()不是返回节点而是在对象中设置游标。这不是我热衷的风格。你应该确保你确定它应该如何工作(例如它如何沟通&#34;未找到&#34;?) - 或者与你的导师澄清。

伪代码是:

foreach line of text
    read parent name and list of children
    tree.findChild(parent)
    if not found, create root node with name of parent
    foreach child
        create new node and add as child of parent
            (by assigning to left-child to the parent...
             ... or assigning to right-sibling of the previous child)

您可以通过多种方式重新排列。例如,您可以构建一个孤立的子项列表:

 Node siblingList = new Node(first child)
 Node tail = head
 while(more children)
     newChild = new Node(next child)
     tail.rightSibling = newChild
     tail = newChild

...然后将该子列表附加到适当的父级。

 parent.leftChild = siblingList