我有一个数据结构,其中节点可以有多个父节点 我有一个我想插入树的节点列表。 列表中的节点包含数据及其父节点的子列表。
我想从这个列表中构建一个树。
private class Treenode {
private List<Treenode> children;
private List<Treenode> parents;
public List<Treenode> getChildren() {
return children;
}
public List<Treenode> getParents() {
return parents;
}
private Info data;
public Info getData() {
return data;
}
public void setData(Info data) {
this.data = data;
}
public Treenode() {
children = new ArrayList<Treenode>();
parents = new ArrayList<Treenode>();
}
public Treenode(Info data) {
children = new ArrayList<Treenode>();
parents = new ArrayList<Treenode>();
this.data = data;
}
public boolean addChild(Treenode n) {
return children.add(n);
}
public boolean removeChild(Treenode n) {
return children.remove(n);
}
public boolean addParent(Treenode n) {
return parents.add(n);
}
public boolean removeParent(Treenode n) {
return parents.remove(n);
}
}
private void scanListAndAddToTree(final List list,Treenode parent){
for (Iterator iter = list.iterator(); iter.hasNext();) {
Info info = (Info) iter.next();
String [] parents = info.getParents();
if(parents==null){ //no parents
Treenode newNode = new Treenode(info);
parent.addChild(newNode);
scanTree(list,newNode);
} else
for (int i = 0; i < parents.length; i++) {
if (parents[i].getID.equals(parent.data.getID())){
Treenode newNode = new Treenode(info);
parent.addChild(newNode);
scanTree(list,newNode);
}
}
}
但我的代码错了:(
递归永远不会停止并重新添加相同的节点
答案 0 :(得分:3)
如果按照以下方式制作课程防弹,则按项目完成的列表插入没有问题。
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class GraphNode<D> {
private D data;
private Set<GraphNode<D>> ins = new HashSet<>();
private Set<GraphNode<D>> outs = new HashSet<>();
public GraphNode(D data) {
this.data = data;
}
public D getData() {
return data;
}
public void setData(D data) {
this.data = data;
}
public Set<GraphNode<D>> getIns() {
return Collections.unmodifiableSet(ins);
}
public Set<GraphNode<D>> getOuts() {
return Collections.unmodifiableSet(outs);
}
public void addIn(GraphNode<D> node) {
if (node == null) {
throw new NullPointerException(); // Never add null.
}
if (ins.add(node)) {
node.outs.add(this);
}
}
public void addOut(GraphNode<D> node) {
if (node == null) {
throw new NullPointerException(); // Never add null.
}
if (outs.add(node)) {
node.ins.add(this);
}
}
}
备注强>
<>
到<GraphNode<D>>
。Info
类参数化为<D>
,以便可以重复使用该类。Set
依赖于Object(指针)相等。public static class Info {
private String id;
private String[] parents;
private String getID() {
return id;
}
public String[] getParents() {
return parents;
}
}
public static class TreeNode extends GraphNode<Info> {
public TreeNode(Info info) {
super(info);
}
}
private void insertGraph(Map<String, TreeNode> allNodes, List<Info> insertList) {
for (Info info : insertList) {
TreeNode newNode = new TreeNode(info);
allNodes.put(info.getID(), newNode);
}
for (TreeNode node : allNodes.values()) {
for (String parentID: node.getData().getParents()) {
TreeNode parentNode = allNodes.get(parentID);
parentNode.addOut(node);
}
}
}
private TreeNode scanTree(Info rootInfo, List<Info> insertList) {
Map<String, TreeNode> allNodes = new HashMap<>();
insertList.add(rootInfo);
insertGraph(allNodes, insertList);
return allNodes.get(rootInfo.getID());
}
由于无法保证单个树具有所有父项,并且Info已包含该结构,因此不需要递归,但需要一组节点。 由于Info可能引用未定义TreeNode的ID,因此需要两个阶段/ fors。