gpt4 book ai didi

java - 在 Tree 中插入一个节点,每个节点有 2 个以上的子节点

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:48:12 25 4
gpt4 key购买 nike

我有一个具有父子关系的数据库表,任何父级都可以有任意数量的子级,但在根级别只有 1 个父级。数据如下所示:

    TagID   ParentTagID   TagName
-------------------------------
1 null a
2 1 b
3 1 c
4 1 d
5 2 e
6 4 f
7 2 g

我想以树格式获取 java 中的记录。虽然我可以使用下面的 SQL 在 SQL 级别本身实现这一点,但我想按原样从数据库中提取数据并在 Java 级别执行处理,以便 Java 和 SQL 之间的连接可以保持最短持续时间以避免任何延迟数据库端。

with cte as
(
select * from TagValue
where ParentTagID is null

union all

select s.* from TagValue s
join cte c on s.ParentTagID = c.TagID
)
select * from cte

在其他有用链接的帮助下使用 Java,我创建了一个如下所示的树:

public class MyTreeNode<T> {
private T data = null;
private List<MyTreeNode<T>> children = new ArrayList<MyTreeNode<T>>();
private MyTreeNode<T> parent = null;

public MyTreeNode(T data) {
this.data = data;
}

public void addChild(MyTreeNode<T> child) {
child.setParent(this);
this.children.add(child);
}

public void addChild(T data) {
MyTreeNode<T> newChild = new MyTreeNode<T>(data);
newChild.setParent(this);
children.add(newChild);
}

public void addChildren(List<MyTreeNode<T>> children) {
for (MyTreeNode<T> t : children) {
t.setParent(this);
}
this.children.addAll(children);
}

public List<MyTreeNode<T>> getChildren() {
return children;
}

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}

private void setParent(MyTreeNode<T> parent) {
this.parent = parent;
}

public MyTreeNode<T> getParent() {
return parent;
}
}

在这棵树中插入对象时,我可以使用下面的代码:

MyTreeNode<Integer> root = new MyTreeNode<Integer>(1);

MyTreeNode<Integer> child1 = new MyTreeNode<Integer>(2);
child1.addChild(3);
child1.addChild(4);

MyTreeNode<Integer> child2 = new MyTreeNode<Integer>(5);
child2.addChild(6);

root.addChild(child1);
root.addChild(child2);
root.addChild(7);

root.addChildren(Arrays.asList(new MyTreeNode<Integer>(8),
new MyTreeNode<Integer>(9), new MyTreeNode<Integer>(10)));

但这是一个静态代码,而标签的数量可以是动态的。我需要一个递归解决方案来根据 ParentTag 值找到一个节点,然后将新标签作为其子标签插入。是否有递归解决方案来执行此操作?如果 Java 1.8 中有任何其他开箱即用的数据结构来执行此操作,那也会很有用。

最佳答案

给定一个 ResultSet,您想自然地构建树结构,如下所示:

while (... has more rows ...) {
addNode(rs.ParentTagID, rs.TagID);

您需要某种类型的容器来存储您的树节点。您可以使用列表,但是在构建树时性能会受到影响;添加一个 child 需要找到它的 parent ,而列表并没有提供快速的方法来做到这一点。一张 map 但是提供 O(1) 查找。

辅助方法 addNode 将保持树的完整:找到父节点,并相应地添加子节点。

总而言之,您正在寻找的动态方法是迭代结果集,并重复调用 addNode() 传递 parentId 和 childId(存储在数据库中)。根节点是一种特殊情况(其中 parentId = null 或 0)并由 addNode() 处理。

对 MyTreeNode 进行了细微修改以返回对象(添加子项时);它曾经是 void 类型。

下面是一些展示这种方法的示例代码。

public class MutipleTreeNode {

static Map<Integer, MyTreeNode<Integer>> nodeMap = new HashMap<>();

public static void main(String[] args) {

// Here you would process your result set
// Rather than simulate a result set, I just build some nodes manually
addNode(0, 1); // Root
addNode(1, 2);
addNode(1, 3);
addNode(1, 4);
addNode(2, 5);
addNode(2, 7);
addNode(4, 6);

printTree();

}

private static void printTree() {
for (MyTreeNode<Integer> node : nodeMap.values()) {
if (node.getParent() == null)
System.out.print("Root node: ");
System.out.println(node.getData()+"; children="+node.getChildren());
}

}

private static void addNode(int parentId, int childId) {
MyTreeNode<Integer> childNode, parentNode;
if (nodeMap.isEmpty())
childNode = new MyTreeNode<Integer>(childId);
else {
parentNode = nodeMap.get(parentId);
childNode = parentNode.addChild(childId);
}
nodeMap.put(childId, childNode);
}

public static class MyTreeNode<T> {
private T data = null;
private List<MyTreeNode<T>> children = new ArrayList<MyTreeNode<T>>();
private MyTreeNode<T> parent = null;

public MyTreeNode(T data) {
this.data = data;
}

public void addChild(MyTreeNode<T> child) {
child.setParent(this);
this.children.add(child);
}

public MyTreeNode<T> addChild(T data) {
MyTreeNode<T> newChild = new MyTreeNode<T>(data);
newChild.setParent(this);
children.add(newChild);
return newChild;
}

public void addChildren(List<MyTreeNode<T>> children) {
for (MyTreeNode<T> t : children) {
t.setParent(this);
}
this.children.addAll(children);
}

public List<MyTreeNode<T>> getChildren() {
return children;
}

public T getData() {
return data;
}

public void setData(T data) {
this.data = data;
}

private void setParent(MyTreeNode<T> parent) {
this.parent = parent;
}

public MyTreeNode<T> getParent() {
return parent;
}

@Override
public String toString() {
return "[data=" + data + "]";
}
}
}

创建输出:

Root node: 1; children=[[data=2], [data=3], [data=4]]
2; children=[[data=5], [data=7]]
3; children=[]
4; children=[[data=6]]
5; children=[]
6; children=[]
7; children=[]

关于java - 在 Tree 中插入一个节点,每个节点有 2 个以上的子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48594776/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com