在Java中是否有标准的Java库类来表示树?
具体来说,我需要表示以下内容:
任意节点上的子树可以有任意数量的子树 每个节点(根节点之后)及其子节点都有字符串值 我需要得到一个给定节点的所有子(某种类型的列表或字符串数组),它的字符串值(即。一个方法,将一个节点作为输入,并返回子节点的所有字符串值作为输出)
是否有任何可用的结构,或者我需要创建我自己的(如果是这样,实施建议将是伟大的)。
在Java中是否有标准的Java库类来表示树?
具体来说,我需要表示以下内容:
任意节点上的子树可以有任意数量的子树 每个节点(根节点之后)及其子节点都有字符串值 我需要得到一个给定节点的所有子(某种类型的列表或字符串数组),它的字符串值(即。一个方法,将一个节点作为输入,并返回子节点的所有字符串值作为输出)
是否有任何可用的结构,或者我需要创建我自己的(如果是这样,实施建议将是伟大的)。
当前回答
public class Tree {
private List<Tree> leaves = new LinkedList<Tree>();
private Tree parent = null;
private String data;
public Tree(String data, Tree parent) {
this.data = data;
this.parent = parent;
}
}
显然,您可以添加实用工具方法来添加/删除子元素。
其他回答
// TestTree.java
// A simple test to see how we can build a tree and populate it
//
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
public class TestTree extends JFrame {
JTree tree;
DefaultTreeModel treeModel;
public TestTree( ) {
super("Tree Test Example");
setSize(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void init( ) {
// Build up a bunch of TreeNodes. We use DefaultMutableTreeNode because the
// DefaultTreeModel can use it to build a complete tree.
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode subroot = new DefaultMutableTreeNode("SubRoot");
DefaultMutableTreeNode leaf1 = new DefaultMutableTreeNode("Leaf 1");
DefaultMutableTreeNode leaf2 = new DefaultMutableTreeNode("Leaf 2");
// Build our tree model starting at the root node, and then make a JTree out
// of it.
treeModel = new DefaultTreeModel(root);
tree = new JTree(treeModel);
// Build the tree up from the nodes we created.
treeModel.insertNodeInto(subroot, root, 0);
// Or, more succinctly:
subroot.add(leaf1);
root.add(leaf2);
// Display it.
getContentPane( ).add(tree, BorderLayout.CENTER);
}
public static void main(String args[]) {
TestTree tt = new TestTree( );
tt.init( );
tt.setVisible(true);
}
}
简单的例子:
public class ArbrePlaner {
public static void main(String[] args) {
ArbrePlaner ll = new ArbrePlaner();
ll.add(1,"A");
ll.add(2,"B");
ll.add(1,"C");
ll.add(3,"D");
ll.add(1,"Z");
for(int i = 0; i < ll.size; i++){
// System.out.println(ll.isIdExist(i));
System.out.println("-----------------");
System.out.println(ll.getIdAt(i)+" :");
linkedList lst = ll.getListDataById(ll.getIdAt(i));
for(int j = 0; j < lst.size; j++){
System.out.println(lst.getElementAt(j));
}
}
}
private int size;
private Noeud root;
public Noeud add(long Id, Object data){
if(isIdExist(Id)){
Noeud nd = getNoeudId(Id);
nd.add(data);
return nd;
}else{
Noeud nd = new Noeud(Id, data, this.root);
this.root = nd;
this.size++;
return nd;
}
}
public Object getDataById(long Id, int x){
Noeud thisNode = this.root;
while(thisNode!=null){
if(thisNode.getId() == Id){
return thisNode.getLl().getElementAt(x);
}
thisNode = thisNode.getNextNoeud();
}
return null;
}
public long getIdAt(int x){
if(size >= x){
Noeud nd = this.root;
for(int i = 0; i<x; i++)try {nd = nd.getNextNoeud();} catch (Exception e) {return -1;}
return nd.getId();
}
return -1;
}
public linkedList getListDataById(long Id){
Noeud thisNode = this.root;
while(thisNode!=null){
if(thisNode.getId() == Id){
return thisNode.getLl();
}
thisNode = thisNode.getNextNoeud();
}
return null;
}
public boolean deleteById(long id){
Noeud thisNode = this.root;
Noeud prevNode = null;
while(thisNode != null){
if(thisNode.getId() == id){
prevNode.setNextNoeud(thisNode.getNextNoeud());
this.setSize(this.getSize()-1);
return true;
}
prevNode = thisNode;
thisNode = thisNode.getNextNoeud();
}
return false;
}
public boolean isIdExist(long Id){
Noeud thisNode = this.root;
while(thisNode!=null){
if(thisNode.getId()== Id){
return true;
}
thisNode = thisNode.getNextNoeud();
}
return false;
}
public boolean isDataExist(long Id, Object data){
if(isIdExist(Id)){
Noeud thisNode = this.root;
while(thisNode!=null){
if(thisNode.getId() == Id){
linkedList ll = thisNode.getLl();
long x = ll.hashCode();
long y = data.hashCode();
if(x==y) return true;
}
thisNode = thisNode.getNextNoeud();
}
}
return false;
}
public Noeud getNoeudId(long Id){
Noeud thisNode = this.root;
while(thisNode!=null){
if(thisNode.getId() == Id){
return thisNode;
}
thisNode = thisNode.getNextNoeud();
}
return null;
}
public ArbrePlaner() {
this.root = root;
}
public ArbrePlaner(Noeud root) {
this.root = root;
}
public ArbrePlaner(int size, Noeud root) {
this.size = size;
this.root = root;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public Noeud getRoot() {
return root;
}
public void setRoot(Noeud root) {
this.root = root;
}
private class Noeud{
private long id;
private Noeud nextNoeud;
private linkedList Ll;
public void add(Object data){
Ll.add(data);
}
public Noeud(long id, Object data ,Noeud nextNoeud){
this.id = id;
this.nextNoeud = nextNoeud;
Ll = new linkedList();
Ll.add(data);
}
public long getId() {
return id;
}
public Noeud(Object data){
Ll.add(data);
}
public void setId(long id) {
this.id = id;
}
public Noeud getNextNoeud() {
return nextNoeud;
}
public void setNextNoeud(Noeud nextNoeud) {
this.nextNoeud = nextNoeud;
}
public linkedList getLl() {
return Ll;
}
public void setLl(linkedList ll) {
Ll = ll;
}
}
}
我写了一个基于“HashMap”的小“TreeMap”类,它支持添加路径:
import java.util.HashMap;
import java.util.LinkedList;
public class TreeMap<T> extends LinkedHashMap<T, TreeMap<T>> {
public void put(T[] path) {
LinkedList<T> list = new LinkedList<>();
for (T key : path) {
list.add(key);
}
return put(list);
}
public void put(LinkedList<T> path) {
if (path.isEmpty()) {
return;
}
T key = path.removeFirst();
TreeMap<T> val = get(key);
if (val == null) {
val = new TreeMap<>();
put(key, val);
}
val.put(path);
}
}
它可以用来存储一个“T”(泛型)类型的树,但(目前)不支持在节点中存储额外的数据。如果你有一个这样的文件:
root, child 1
root, child 1, child 1a
root, child 1, child 1b
root, child 2
root, child 3, child 3a
然后你可以通过执行:
TreeMap<String> root = new TreeMap<>();
Scanner scanner = new Scanner(new File("input.txt"));
while (scanner.hasNextLine()) {
root.put(scanner.nextLine().split(", "));
}
你会得到一棵漂亮的树。它应该很容易适应你的需要。
在这里:
public class Tree<T> {
private Node<T> root;
public Tree(T rootData) {
root = new Node<T>();
root.data = rootData;
root.children = new ArrayList<Node<T>>();
}
public static class Node<T> {
private T data;
private Node<T> parent;
private List<Node<T>> children;
}
}
这是一个基本的树结构,可用于String或任何其他对象。实现简单的树来满足您的需要是相当容易的。
您需要添加的只是用于添加、删除、遍历和构造函数的方法。节点是树的基本构建块。
如果您正在编写白板代码、进行面试,或者只是计划使用树,那么这些内容就有点冗长了。
应该进一步说,树不像Pair那样存在的原因是,你应该将你的数据封装在使用它的类中,最简单的实现是这样的:
/***
/* Within the class that's using a binary tree for any reason. You could
/* generalize with generics IFF the parent class needs different value types.
*/
private class Node {
public String value;
public Node[] nodes; // Or an Iterable<Node> nodes;
}
这就是任意宽度的树。
如果你想要一个二叉树,它通常更容易使用命名字段:
private class Node { // Using package visibility is an option
String value;
Node left;
Node right;
}
或者如果你想要一个trie
private class Node {
String value;
Map<char, Node> nodes;
}
现在你说你想要
给定一个表示给定节点的输入字符串,能够获得所有的子节点(某种类型的列表或字符串数组)
听起来像是你的家庭作业。 但既然我有理由相信任何最后期限都已经过去了……
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
public class kidsOfMatchTheseDays {
static private class Node {
String value;
Node[] nodes;
}
// Pre-order; you didn't specify.
static public List<String> list(Node node, String find) {
return list(node, find, new ArrayList<String>(), false);
}
static private ArrayList<String> list(
Node node,
String find,
ArrayList<String> list,
boolean add) {
if (node == null) {
return list;
}
if (node.value.equals(find)) {
add = true;
}
if (add) {
list.add(node.value);
}
if (node.nodes != null) {
for (Node child: node.nodes) {
list(child, find, list, add);
}
}
return list;
}
public static final void main(String... args) {
// Usually never have to do setup like this, so excuse the style
// And it could be cleaner by adding a constructor like:
// Node(String val, Node... children) {
// value = val;
// nodes = children;
// }
Node tree = new Node();
tree.value = "root";
Node[] n = {new Node(), new Node()};
tree.nodes = n;
tree.nodes[0].value = "leftish";
tree.nodes[1].value = "rightish-leafy";
Node[] nn = {new Node()};
tree.nodes[0].nodes = nn;
tree.nodes[0].nodes[0].value = "off-leftish-leaf";
// Enough setup
System.out.println(Arrays.toString(list(tree, args[0]).toArray()));
}
}
这让你使用:
$ java kidsOfMatchTheseDays leftish
[leftish, off-leftish-leaf]
$ java kidsOfMatchTheseDays root
[root, leftish, off-leftish-leaf, rightish-leafy]
$ java kidsOfMatchTheseDays rightish-leafy
[rightish-leafy]
$ java kidsOfMatchTheseDays a
[]