java tea collection_Java树数据结构?

有一个好的可用(标准Java)数据结构来表示Java中的树吗?

具体来说,我需要代表以下内容:

任何节点上的树都可以有任意数量的子级

每个节点(在根之后)只是一个字符串(其子节点也是字符串)

我需要能够让所有的子节点(某种列表或字符串数组)都得到一个表示给定节点的输入字符串。

是否有可用的结构来解决这个问题,或者我是否需要创建自己的结构(如果是这样的话,实现建议会很好)。

如果您正在使用Java 8,并且希望通过流、过滤等方式遍历节点,那么您可能需要查看榴莲Github. COM/DeField/榴莲。

您可以使用此API:sourceforge.net/p/treeds4j

在这里:

public class Tree {

private Node root;

public Tree(T rootData) {

root = new Node();

root.data = rootData;

root.children = new ArrayList>();

}

public static class Node {

private T data;

private Node parent;

private List> children;

}

}

这是一个基本的树结构,可以用于String或任何其他对象。实现简单的树来做您需要的事情是相当容易的。

您需要添加的只是用于添加到、移除、遍历和构造函数的方法。Node是Tree的基本组成部分。

如果要从子节点获取路径,也可能需要父字段。

是的,如果你想上树,你需要一个家长参考。

严格来说,没有必要使用Tree类,因为每个Node本身都可以看作一棵树。

@Joa,我喜欢有一个包含根的结构。可以将方法添加到树类中,这样可以更合理地调用树而不是单个节点。

@贾斯汀:例如?这是一个诚实的问题:我想不出一个对整棵树都有意义的方法,而对一个子树却没有意义。

@约阿希姆,我想我喜欢抽象出这棵树的表现形式。可以使用基于数组的表示交换节点结构。这就是为什么我不喜欢公开一个节点。

@Justin:如果不公开节点,如何编写一个方法来表示"将该节点作为子节点添加到另一个节点"?只有在您实现一些ADT并使用树内部语言(例如,在TreeSet中)时,该参数才有意义。但我理解这个问题是关于一个实际的树广告。

@Joa,我通常在一些内部代码中使用树。所以,这就是我写这篇文章的方式。习惯的力量。而且,我认为这是一个很好的实践。我不觉得你失去了任何东西的外部树结构。而且,如果您使用的是一个具体的树,而不仅仅是节点,就更容易理解了。

我同意@joa的观点,认为不需要树类。我更喜欢在代码中显式地保留树的递归性质,不添加单独的树类,并且一致地使用节点类。相反,如果需要清楚地表明您正在处理树的根节点,那么我将变量命名为"tree"或"root"。

要节省40分钟,请在此处使用更完整的示例

@Joa"严格来说树类课程是不必要的"在什么意义上?从语义上讲(从数据结构的角度来看),您的注释不正确。根节点只是树概念的众多实现之一。例如,一个人不应该有一个类dog并说cat=new dog(),因为一只狗(为了我们所关心的)和猫做同样的事情。

@Elmarce:我之所以说没有严格必要,是因为它没有添加任何操作,您也不能在任何给定的子树(也就是"节点")上执行这些操作。如果您选择使用树类(当然这是一个完全有效的选择),那么您所要做的就是限制可以将其视为树的内容。如果我不区分一棵树和一个节点,那么我就可以把每一个子树都视为一棵树。这可能不是您的特定域所要求的,所以您可能仍然想要一个树类。

@琼,我四岁大,完全同意你的看法。不上树课。

为我分离类(接口)。Tree有isEmpty()和size(),TreeNode有childCount()、descendentCount()和toTree()。我发现这是对实际对象的更清晰的描述,并且在编写实现(而不是公共链接版本)时提供了更大的灵活性。不确定如果只有一个节点类,如何表示空树?

@Barney,这也是一个有趣的实现……但即使是那些Tree类方法也可以用某种方式在TreeNode类中实现。size()与childCount()有什么不同?对于isEmpty(),如果根TreeNode为null则为空,因此可以用空校验代替isEmpty()方法。

当然,@scott scooter weidenkopf,你可以用任何一种方式。但是,举例来说,为了使一棵树变平,我发现array = new Object[tree.size()]比array = new Object[(node == null ? 0 : (node.descendentCount() + 1))]可读得多。

@如果您希望它是AVL树,则需要一个节点类,因为旋转树可以更改根。(举个例子)

还有另一种树结构:

public class TreeNode implements Iterable> {

T data;

TreeNode parent;

List> children;

public TreeNode(T data) {

this.data = data;

this.children = new LinkedList>();

}

public TreeNode addChild(T child) {

TreeNode childNode = new TreeNode(child);

childNode.parent = this;

this.children.add(childNode);

return childNode;

}

// other features ...

}

样品使用情况:

TreeNode root = new TreeNode("root");

{

TreeNode node0 = root.addChild("node0");

TreeNode node1 = root.addChild("node1");

TreeNode node2 = root.addChild("node2");

{

TreeNode node20 = node2.addChild(null);

TreeNode node21 = node2.addChild("node21");

{

TreeNode node210 = node20.addChild("node210");

}

}

}

奖金见完全羽化的树:

迭代器

搜索

爪哇/ C

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

刚发现你的图书馆非常有用。谢谢您。但我想知道如何根据父级和子级之间的引用关系动态填充树结构。举个例子,我有一个会员1赞助另一个会员2,会员2赞助会员3等等。已经有了表记录关系,但不确定是否可以使用您的库将它们填充到树中。

截至2016年,该链接不包含源文件或下载

在我看来,这个答案三年后以上的高分答案,是更干净的一个。但是,我将用arraylist替换linkedlist。

我会为孩子们准备一套。

我可能是错的,但在这个实现中,您必须在每次调用next()之前调用hasNext(),以获得有效的结果。这不是Iterator规范的一部分。

实际上,JDK中实现了一个非常好的树结构。

看看javax.swing.tree、treemodel和treenode。它们被设计为与JTreePanel一起使用,但实际上,它们是一个非常好的树实现,并且没有什么能阻止您在没有Swing接口的情况下使用它。

注意,对于Java 9,您可能不希望使用这些类,因为它们将不存在于"紧凑配置文件"中。

是的,我以前用过,他们会做你想从树上做的任何事。我能想到的唯一缺点是它们各自实现类的名称的长度:defaultTreeModel和defaultMutableTreeNode。冗长,但我想这并不重要。

解决这个问题的好方法是创建两个静态方法newModel()和newNode(),然后静态导入它们。

我将避免在与Swing无关的函数上使用Swing库。这是糟糕的编码实践。你永远不知道Swing是如何实现它们的树的,它们的依赖关系是什么,这在未来会如何改变。Swing不是实用程序库,而是UI库。

我认为糟糕的编码实践有点苛刻。

JavaX.SWECUT.TeReTeMeDell是一个公共接口(恰好像Java.UTI.List),它不会有不兼容的更改。另外一个优点是,您可以在开发时轻松调试/可视化树。

@杰索普,我知道现在发表评论已经很晚了。但我同意你的观点,使用图书馆对初学者来说可能是一种不好的做法。

您应该避免使用这些类,因为将来您的代码可能必须在紧凑的概要文件上运行。在这些概要文件中,Swing包中的类不可用。(参见Oracle、COM/TeaTeWorks/Java/Ent/Realth/Tea//Helip;)。我已经不得不重构那些除了使用TreeModel和TreeNode之外根本没有用户界面的代码。这是一个应该避免的风险…

@汤塞德尔似乎是一个合理的观点,更新了答案让人们真正看到,我怀疑评论中的信息并没有真正得到太多关注。

"没有什么能阻止你在没有Swing界面的情况下使用它",直到你意识到你的android apk充斥着你只需要一个或两个类的库,占总大小的50%…

@弗朗玛佐亚更有理由在JDK中使用某些运输工具:)..当然,我也不知道安卓飞船是否在运行时摇摆:(

不,事实上,它甚至不能在Android上工作…我认为在某些情况下使用第三方库是可以的,但是只为这个添加Swing是不合理的,即使它是一个桌面项目。

这个怎么样?

import java.util.ArrayList;

import java.util.Collection;

import java.util.HashMap;

/**

* @author ycoppel@google.com (Yohann Coppel)

*

* @param

*          Object's type in the tree.

*/

public class Tree {

private T head;

private ArrayList> leafs = new ArrayList>();

private Tree parent = null;

private HashMap> locate = new HashMap>();

public Tree(T head) {

this.head = head;

locate.put(head, this);

}

public void addLeaf(T root, T leaf) {

if (locate.containsKey(root)) {

locate.get(root).addLeaf(leaf);

} else {

addLeaf(root).addLeaf(leaf);

}

}

public Tree addLeaf(T leaf) {

Tree t = new Tree(leaf);

leafs.add(t);

t.parent = this;

t.locate = this.locate;

locate.put(leaf, t);

return t;

}

public Tree setAsParent(T parentRoot) {

Tree t = new Tree(parentRoot);

t.leafs.add(this);

this.parent = t;

t.locate = this.locate;

t.locate.put(head, this);

t.locate.put(parentRoot, t);

return t;

}

public T getHead() {

return head;

}

public Tree getTree(T element) {

return locate.get(element);

}

public Tree getParent() {

return parent;

}

public Collection getSuccessors(T root) {

Collection successors = new ArrayList();

Tree tree = getTree(root);

if (null != tree) {

for (Tree leaf : tree.leafs) {

successors.add(leaf.head);

}

}

return successors;

}

public Collection> getSubTrees() {

return leafs;

}

public static Collection getSuccessors(T of, Collection> in) {

for (Tree tree : in) {

if (tree.locate.containsKey(of)) {

return tree.getSuccessors(of);

}

}

return new ArrayList();

}

@Override

public String toString() {

return printTree(0);

}

private static final int indent = 2;

private String printTree(int increment) {

String s ="";

String inc ="";

for (int i = 0; i < increment; ++i) {

inc = inc +"";

}

s = inc + head;

for (Tree child : leafs) {

s +="

" + child.printTree(increment + indent);

}

return s;

}

}

如何在使用此类对象创建的树上实现DFS?

如何使用该类实现删除叶?

头场的作用是什么?

如果这个类有一些文档,那就太好了。我不太明白像setAsParent或getHead这样的方法会做什么,现在我真的可以在树数据结构上获得一些帮助。即使文档的原始源也没有注释。

我写了一个处理普通树的小库。它比秋千轻得多。我也有一个Maven项目。

我现在正在使用它,工作得很出色。必须为我自己的定制显著地更改源代码,但这是一个很好的起点。谢谢!

public class Tree {

private List leaves = new LinkedList();

private Tree parent = null;

private String data;

public Tree(String data, Tree parent) {

this.data = data;

this.parent = parent;

}

}

显然,您可以添加实用程序方法来添加/删除子项。

您应该首先定义树是什么(对于域),最好先定义接口。并不是所有的树结构都是可修改的,能够添加和删除节点应该是一个可选的特性,所以我们为此做了一个额外的接口。

不需要创建保存值的节点对象,事实上,我认为这是大多数树实现中的一个主要设计缺陷和开销。如果你看Swing,TreeModel没有节点类(只有DefaultTreeModel使用TreeNode,因为它们不是真正需要的。

public interface Tree extends Serializable {

List getRoots ();

N getParent (N node);

List getChildren (N node);

}

可变树结构(允许添加和删除节点):

public interface MutableTree extends Tree {

boolean add (N parent, N node);

boolean remove (N node, boolean cascade);

}

考虑到这些接口,使用树的代码不必太关心树是如何实现的。这允许您使用通用实现和专用实现,通过将函数委托给另一个API来实现树。

示例:文件树结构

public class FileTree implements Tree {

@Override

public List getRoots() {

return Arrays.stream(File.listRoots()).collect(Collectors.toList());

}

@Override

public File getParent(File node) {

return node.getParentFile();

}

@Override

public List getChildren(File node) {

if (node.isDirectory()) {

File[] children = node.listFiles();

if (children != null) {

return Arrays.stream(children).collect(Collectors.toList());

}

}

return Collections.emptyList();

}

}

示例:通用树结构(基于父/子关系):

public class MappedTreeStructure implements MutableTree {

public static void main(String[] args) {

MutableTree 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 nodeParent = new HashMap<>();

private final LinkedHashSet 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 getRoots() {

return getChildren(null);

}

@Override

public N getParent(N node) {

checkNotNull(node,"node");

return nodeParent.get(node);

}

@Override

public List getChildren(N node) {

List 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('

');

prefix =" " + prefix;

}

for (N child : getChildren(node)) {

dumpNodeStructure(builder, child, prefix);

}

}

}

当我执行tree.a d d("a","b");tree.add("a","c");tree.add("c","d");tree.add("e","a");e是a的父级时,我面临着一个问题。我们该怎么做?

嗨,桑尼克,上面的代码中有一个错误,导致最后一个关系无法添加。现在已经修复了,我还添加了非空检查和(更重要的是):循环检查,以防止违反树结构(将代码或其祖先之一作为子代添加到自身中)。谢谢你的提示!

我修复了这个bug如果有人想修复这个bug,你要做的就是看看add方法是否返回false,如果返回false,只需创建一个temp new linkedhashset并将树的节点列表克隆到其中,你就可以清除树,添加上一步没有添加的父节点,然后将所有temp node添加回pa。租树…不过,谢谢你的结构!

只需从接口中删除那些无用的公共修饰符。

如何从中生成JSON数组

没有答案提到过简化的工作代码,所以这里是:

public class TreeNodeArray {

public T value;

public final  java.util.List> kids =  new java.util.ArrayList>();

}

您可以使用Java的任何XML API作为文档和节点,因为XML是一个带字符串的树结构。

好主意,我们可以使用内存中的XML模式,使用dom4j+jaxen xpath来搜索节点。

在Java中有一些树数据结构,例如JDK Swing中的Debug ToMababeleReNoDE、斯坦福解析器包中的树和其他玩具代码。但这些都不足以满足一般用途。

Java树项目试图在Java中提供另一种通用树数据结构。这个和其他的区别是

完全免费。你可以在任何地方使用它(家庭作业除外:p)

小而一般。我将数据结构的所有内容都放在一个类文件中,这样就很容易复制/粘贴。

不仅仅是玩具。我知道几十个Java树代码,只能处理二叉树或有限的操作。这棵树结比那要多得多。它提供了不同的访问节点的方法,如预排序、后排序、breadthfirst、leaves、根路径等,并且还提供了迭代器以充分利用这些方法。

将添加更多的实用程序。我愿意增加更多的操作来使这个项目更全面,特别是如果你通过GitHub发送一个请求。

blog.pengyifan.com/yet-another-java-树结构

按照加雷斯的回答,查看默认可变树型。它不是通用的,但在其他方面似乎符合这个要求。即使它在javax.swing包中,它也不依赖于任何awt或swing类。实际上,源代码实际上有注释// ISSUE: this class depends on nothing in AWT -- move to java.util?

如果你在做白板编码,面试,甚至只是打算用一棵树,这些都有点冗长。

还应该说,树不在其中的原因,比如说,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 nodes;

}

这真的适用于任意宽度的树。

如果需要二叉树,通常更容易与命名字段一起使用:

private class Node { // Using package visibility is an option

String value;

Node left;

Node right;

}

或者如果你想要一个特里尔:

private class Node {

String value;

Map nodes;

}

现在你说你想要

to be able to get all the children (some sort of list or array of Strings) given an input string representing a given node

听起来像你的家庭作业。不过,既然我有理由确定现在已经过了最后期限…

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 list(Node node, String find) {

return list(node, find, new ArrayList(), false);

}

static private ArrayList list(

Node node,

String find,

ArrayList 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

[]

public abstract class Node {

List children;

public List getChidren() {

if (children == null) {

children = new ArrayList<>();

}

return chidren;

}

}

简单易用。要使用它,请扩展它:

public class MenuItem extends Node {

String label;

String href;

...

}

由于问题要求提供可用的数据结构,因此可以从列表或数组构造树:

Object[] tree = new Object[2];

tree[0] ="Hello";

{

Object[] subtree = new Object[2];

subtree[0] ="Goodbye";

subtree[1] ="";

tree[1] = subtree;

}

instanceof可用于确定元素是子树还是终端节点。

相当丑陋。如果您的数据对象可能是数组和列表,那么它就不起作用。

我同意这很难看。Objects要么是叶对象(例如,Strings),要么是分支(由数组表示)。它确实有效:该代码将被编译,并创建一个String的小树。

例如:

import java.util.ArrayList;

import java.util.List;

/**

*

* @author X2

*

* @param

*/

public class HisTree

{

private Node root;

public HisTree(T rootData)

{

root = new Node();

root.setData(rootData);

root.setChildren(new ArrayList>());

}

}

class Node

{

private T data;

private Node parent;

private List> children;

public T getData() {

return data;

}

public void setData(T data) {

this.data = data;

}

public Node getParent() {

return parent;

}

public void setParent(Node parent) {

this.parent = parent;

}

public List> getChildren() {

return children;

}

public void setChildren(List> children) {

this.children = children;

}

}

我写了一个基于"hashmap"的小"treemap"类,它支持添加路径:

import java.util.HashMap;

import java.util.LinkedList;

public class TreeMap extends LinkedHashMap> {

public void put(T[] path) {

LinkedList list = new LinkedList<>();

for (T key : path) {

list.add(key);

}

return put(list);

}

public void put(LinkedList path) {

if (path.isEmpty()) {

return;

}

T key = path.removeFirst();

TreeMap 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 root = new TreeMap<>();

Scanner scanner = new Scanner(new File("input.txt"));

while (scanner.hasNextLine()) {

root.put(scanner.nextLine().split(","));

}

你会得到一棵漂亮的树。它应该很容易适应你的需要。

在过去,我只是使用了一个嵌套的映射。这是我今天用的,很简单,但它符合我的需要。也许这对另一个有用。

import com.fasterxml.jackson.annotation.JsonValue;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;

import java.util.Map;

import java.util.TreeMap;

/**

* Created by kic on 16.07.15.

*/

public class NestedMap {

private final Map root = new HashMap<>();

public NestedMap put(K key) {

Object nested = root.get(key);

if (nested == null || !(nested instanceof NestedMap)) root.put(key, nested = new NestedMap<>());

return (NestedMap) nested;

}

public Map.Entry put(K key, V value) {

root.put(key, value);

return (Map.Entry) root.entrySet().stream().filter(e -> ((Map.Entry) e).getKey().equals(key)).findFirst().get();

}

public NestedMap get(K key) {

return (NestedMap) root.get(key);

}

public V getValue(K key) {

return (V) root.get(key);

}

@JsonValue

public Map getRoot() {

return root;

}

public static void main(String[] args) throws Exception {

NestedMap test = new NestedMap<>();

test.put("a").put("b").put("c", 12);

Map.Entry foo = test.put("a").put("b").put("d", 12);

test.put("b", 14);

ObjectMapper mapper = new ObjectMapper();

System.out.println(mapper.writeValueAsString(test));

foo.setValue(99);

System.out.println(mapper.writeValueAsString(test));

System.out.println(test.get("a").get("b").getValue("d"));

}

}

// 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);

}

}

请不要只是丢弃代码-解释它做了什么,特别是为什么它比所有其他答案都不同(更好)。

Java中没有特定的数据结构,适合您的需求。您的需求非常具体,因此需要设计自己的数据结构。查看您的需求,任何人都可以说您需要某种具有特定功能的n元树。您可以按以下方式设计数据结构:

树节点的结构类似于节点中的内容,子节点列表类似于:类节点字符串值;列出子级;

您需要检索给定字符串的子级,因此您可以有两种方法:1:节点searchnode(string str),将返回与给定输入值相同的节点(使用bfs进行搜索)2:列表get children(string str):此方法将在内部调用searchnode以获取具有相同字符串的节点,然后创建al的列表l字符串值的子级和返回。

您还需要在树中插入一个字符串。您必须编写一个方法,比如void insert(字符串父级,字符串值):这将再次搜索值等于父级的节点,然后您可以创建具有给定值的节点,并将其添加到找到的父级的子级列表中。

我建议您在类node string value;list children;中编写节点的结构,在另一个nodeUtils类中编写所有其他方法,如search、insert和getchildren,这样您也可以通过树根在特定的树上执行操作,例如:class nodeUtils公共静态节点搜索(node root,string value)//执行bfs并返回node

您可以使用ApacheJMeter中包含的hashtree类,它是雅加达项目的一部分。

hashtree类包含在包org.apache.jorphan.collections中。虽然这个包不是在JMeter项目之外发布的,但是您可以很容易地获得它:

1)下载JMeter源。

2)创建新包。

3)复制到it/src/jorphan/org/apache/jorphan/collections/。除data.java外的所有文件

4)也复制/src/jorphan/org/apache/jorphan/util/jorphanutils.java

5)hashtree可以使用。

我编写了一个树库,它可以很好地使用Java8,并且没有其他依赖项。它还提供了对函数式编程的一些想法的松散解释,并允许您映射/过滤/修剪/搜索整个树或子树。

网址:https://github.com/rutledgepaulv/prune

这个实现在索引方面没有做任何特殊的工作,我也没有偏离递归,所以使用大型树时性能可能会降低,您可能会破坏堆栈。但是如果你只需要一棵小到中等深度的直截了当的树,我认为它足够好用了。它提供了一个健全(基于值)的平等定义,它还具有一个ToString实现,让您可以可视化树!

请检查下面的代码,其中我使用了树数据结构,而不使用集合类。代码可能有缺陷/改进,但请使用此代码仅供参考。

package com.datastructure.tree;

public class BinaryTreeWithoutRecursion {

private TreeNode root;

public BinaryTreeWithoutRecursion (){

root = null;

}

public void insert(T data){

root =insert(root, data);

}

public TreeNode  insert(TreeNode node, T data ){

TreeNode newNode = new TreeNode<>();

newNode.data = data;

newNode.right = newNode.left = null;

if(node==null){

node = newNode;

return node;

}

Queue> queue = new Queue>();

queue.enque(node);

while(!queue.isEmpty()){

TreeNode temp= queue.deque();

if(temp.left!=null){

queue.enque(temp.left);

}else

{

temp.left = newNode;

queue =null;

return node;

}

if(temp.right!=null){

queue.enque(temp.right);

}else

{

temp.right = newNode;

queue =null;

return node;

}

}

queue=null;

return node;

}

public void inOrderPrint(TreeNode root){

if(root!=null){

inOrderPrint(root.left);

System.out.println(root.data);

inOrderPrint(root.right);

}

}

public void postOrderPrint(TreeNode root){

if(root!=null){

postOrderPrint(root.left);

postOrderPrint(root.right);

System.out.println(root.data);

}

}

public void preOrderPrint(){

preOrderPrint(root);

}

public void inOrderPrint(){

inOrderPrint(root);

}

public void postOrderPrint(){

inOrderPrint(root);

}

public void preOrderPrint(TreeNode root){

if(root!=null){

System.out.println(root.data);

preOrderPrint(root.left);

preOrderPrint(root.right);

}

}

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

BinaryTreeWithoutRecursion ls=  new BinaryTreeWithoutRecursion <>();

ls.insert(1);

ls.insert(2);

ls.insert(3);

ls.insert(4);

ls.insert(5);

ls.insert(6);

ls.insert(7);

//ls.preOrderPrint();

ls.inOrderPrint();

//ls.postOrderPrint();

}

}

"不使用集合类"啊?那么队列类来自哪里呢?如上所述,它是一个二叉树,在第一个需求(任何数量的子节点)失败。

可以在Java.UTL.*中使用TeeSeTepe类。它像二进制搜索树一样工作,所以已经排序了。Treeset类实现ITerable、Collection和Set接口。您可以像集合一样使用迭代器遍历树。

TreeSet treeSet = new TreeSet();

Iterator it  = treeSet.Iterator();

while(it.hasNext()){

...

}

您可以检查,Java doc和其他一些。

不使用集合框架的树的自定义树实现。它包含树实现中需要的不同的基本操作。

class Node {

int data;

Node left;

Node right;

public Node(int ddata, Node left, Node right) {

this.data = ddata;

this.left = null;

this.right = null;

}

public void displayNode(Node n) {

System.out.print(n.data +"");

}

}

class BinaryTree {

Node root;

public BinaryTree() {

this.root = null;

}

public void insertLeft(int parent, int leftvalue ) {

Node n = find(root, parent);

Node leftchild = new Node(leftvalue, null, null);

n.left = leftchild;

}

public void insertRight(int parent, int rightvalue) {

Node n = find(root, parent);

Node rightchild = new Node(rightvalue, null, null);

n.right = rightchild;

}

public void insertRoot(int data) {

root = new Node(data, null, null);

}

public Node getRoot() {

return root;

}

public Node find(Node n, int key) {

Node result = null;

if (n == null)

return null;

if (n.data == key)

return n;

if (n.left != null)

result = find(n.left, key);

if (result == null)

result = find(n.right, key);

return result;

}

public int getheight(Node root){

if (root == null)

return 0;

return Math.max(getheight(root.left), getheight(root.right)) + 1;

}

public void printTree(Node n) {

if (n == null)

return;

printTree(n.left);

n.displayNode(n);

printTree(n.right);

}

}

这是一个二叉树,它在操作的第一个要求时失败了。

投反对票是因为我同意@philho

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值