Java树数据结构? [关闭]

本文翻译自:Java tree data-structure? [closed]

Is there a good available (standard Java) data structure to represent a tree in Java? 是否有一个良好的可用(标准Java)数据结构来表示Java中的树?

Specifically I need to represent the following: 具体来说,我需要代表以下内容:

  • The tree at any node can have an arbitrary number of children 任何节点上的树都可以有任意数量的子节点
  • Each node (after the root) is just a String (whose children are also Strings) 每个节点(在根之后)只是一个String(其子节点也是字符串)
  • I need to be able to get all the children (some sort of list or array of Strings) given an input string representing a given node 给定一个表示给定节点的输入字符串,我需要能够获得所有子节点(某种列表或字符串数​​组)

Is there an available structure for this or do I need to create my own (if so implementation suggestions would be great). 是否有可用的结构或我是否需要创建自己的结构(如果是这样的实现建议会很好)。


#1楼

参考:https://stackoom.com/question/EmLm/Java树数据结构-关闭


#2楼

您可以使用Java的任何XML API作为Document和Node..as XML是带有字符串的树结构


#3楼

No answer mentions over-simplified but working code, so here it is: 没有回答提到过度简化但工作的代码,所以这里是:

public class TreeNodeArray<T> {
    public T value;
    public final  java.util.List<TreeNodeArray<T>> kids =  new java.util.ArrayList<TreeNodeArray<T>>();
}

#4楼

Since the question asks for an available data structure, a tree can be constructed from lists or arrays: 由于该问题要求可用的数据结构,因此可以从列表或数组构造树:

Object[] tree = new Object[2];
tree[0] = "Hello";
{
  Object[] subtree = new Object[2];
  subtree[0] = "Goodbye";
  subtree[1] = "";
  tree[1] = subtree;
}

instanceof can be used to determine whether an element is a subtree or a terminal node. instanceof可用于确定元素是子树还是终端节点。


#5楼

Yet another tree structure: 另一种树形结构:

public class TreeNode<T> implements Iterable<TreeNode<T>> {

    T data;
    TreeNode<T> parent;
    List<TreeNode<T>> children;

    public TreeNode(T data) {
        this.data = data;
        this.children = new LinkedList<TreeNode<T>>();
    }

    public TreeNode<T> addChild(T child) {
        TreeNode<T> childNode = new TreeNode<T>(child);
        childNode.parent = this;
        this.children.add(childNode);
        return childNode;
    }

    // other features ...

}

Sample usage: 样品用法:

TreeNode<String> root = new TreeNode<String>("root");
{
    TreeNode<String> node0 = root.addChild("node0");
    TreeNode<String> node1 = root.addChild("node1");
    TreeNode<String> node2 = root.addChild("node2");
    {
        TreeNode<String> node20 = node2.addChild(null);
        TreeNode<String> node21 = node2.addChild("node21");
        {
            TreeNode<String> node210 = node20.addChild("node210");
        }
    }
}

BONUS 奖金
See fully-fledged tree with: 查看完全成熟的树:

  • iterator 迭代器
  • searching 搜索
  • Java/C# 的Java / C#

https://github.com/gt4dev/yet-another-tree-structure https://github.com/gt4dev/yet-another-tree-structure


#6楼

You should start by defining what a tree is (for the domain), this is best done by defining the interface first. 您应该首先定义树是什么(对于域),最好先通过定义接口来完成。 Not all trees structures are modifyable, being able to add and remove nodes should be an optional feature, so we make an extra interface for that. 并非所有树结构都是可修改的,能够添加删除节点应该是一个可选功能,因此我们为此创建了一个额外的接口。

There's no need to create node objects which hold the values , in fact I see this as a major design flaw and overhead in most tree implementations. 没有必要创建保存值的节点对象 ,事实上我认为这是大多数树实现中的主要设计缺陷和开销。 If you look at Swing, the TreeModel is free of node classes (only DefaultTreeModel makes use of TreeNode ), as they are not really needed. 如果你看看Swing, TreeModel没有节点类(只有DefaultTreeModel使用TreeNode ),因为它们并不是真正需要的。

public interface Tree <N extends Serializable> extends Serializable {
    List<N> getRoots ();
    N getParent (N node);
    List<N> getChildren (N node);
}

Mutable tree structure (allows to add and remove nodes): 可变树结构(允许添加和删除节点):

public interface MutableTree <N extends Serializable> extends Tree<N> {
    boolean add (N parent, N node);
    boolean remove (N node, boolean cascade);
}

Given these interfaces, code that uses trees doesn't have to care much about how the tree is implemented. 给定这些接口,使用树的代码不必太在意树的实现方式。 This allows you to use generic implementations as well as specialized ones, where you realize the tree by delegating functions to another API. 这允许您使用通用实现以及专用实现,您可以通过将函数委托给另一个API来实现树。

Example: file tree structure 示例: 文件树结构

public class FileTree implements Tree<File> {

    @Override
    public List<File> getRoots() {
        return Arrays.stream(File.listRoots()).collect(Collectors.toList());
    }

    @Override
    public File getParent(File node) {
        return node.getParentFile();
    }

    @Override
    public List<File> getChildren(File node) {
        if (node.isDirectory()) {
            File[] children = node.listFiles();
            if (children != null) {
                return Arrays.stream(children).collect(Collectors.toList());
            }
        }
        return Collections.emptyList();
    }
}

Example: generic tree structure (based on parent/child relations): 示例: 通用树结构 (基于父/子关系):

public class MappedTreeStructure<N extends Serializable> implements MutableTree<N> {

    public static void main(String[] args) {

        MutableTree<String> tree = new MappedTreeStructure<>();
        tree.add("A", "B");
        tree.add("A", "C");
        tree.add("C", "D");
        tree.add("E", "A");
        System.out.println(tree);
    }

    private final Map<N, N> nodeParent = new HashMap<>();
    private final LinkedHashSet<N> nodeList = new LinkedHashSet<>();

    private void checkNotNull(N node, String parameterName) {
        if (node == null)
            throw new IllegalArgumentException(parameterName + " must not be null");
    }

    @Override
    public boolean add(N parent, N node) {
        checkNotNull(parent, "parent");
        checkNotNull(node, "node");

        // check for cycles
        N current = parent;
        do {
            if (node.equals(current)) {
                throw new IllegalArgumentException(" node must not be the same or an ancestor of the parent");
            }
        } while ((current = getParent(current)) != null);

        boolean added = nodeList.add(node);
        nodeList.add(parent);
        nodeParent.put(node, parent);
        return added;
    }

    @Override
    public boolean remove(N node, boolean cascade) {
        checkNotNull(node, "node");

        if (!nodeList.contains(node)) {
            return false;
        }
        if (cascade) {
            for (N child : getChildren(node)) {
                remove(child, true);
            }
        } else {
            for (N child : getChildren(node)) {
                nodeParent.remove(child);
            }
        }
        nodeList.remove(node);
        return true;
    }

    @Override
    public List<N> getRoots() {
        return getChildren(null);
    }

    @Override
    public N getParent(N node) {
        checkNotNull(node, "node");
        return nodeParent.get(node);
    }

    @Override
    public List<N> getChildren(N node) {
        List<N> children = new LinkedList<>();
        for (N n : nodeList) {
            N parent = nodeParent.get(n);
            if (node == null && parent == null) {
                children.add(n);
            } else if (node != null && parent != null && parent.equals(node)) {
                children.add(n);
            }
        }
        return children;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        dumpNodeStructure(builder, null, "- ");
        return builder.toString();
    }

    private void dumpNodeStructure(StringBuilder builder, N node, String prefix) {
        if (node != null) {
            builder.append(prefix);
            builder.append(node.toString());
            builder.append('\n');
            prefix = "  " + prefix;
        }
        for (N child : getChildren(node)) {
            dumpNodeStructure(builder, child, prefix);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值