我需要一個平坦的列表轉換爲一棵樹。與我發現的解決方案相反,我還需要考慮同一個對象可以多次與父對象關聯。而且我需要檢測週期,以避免無限循環。有沒有人有一個好的算法呢?
示例清單(請注意,列表中的項目可能是隨機IDS不分先後):
null -> 1
1 -> 2
1 -> 3
2 -> 3
3 -> 4
所以樹是這樣的:
null
--> 1
--> 2
--> 3
--> 4
--> 3
--> 4
在換句話說,節點4的結構(如果它有孩子的話)將不得不被複制。
代碼
我在Java中的做法,但只有一個作品,未經3 -> 4
關聯。
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
public class List2Tree {
public static void main(String args[]) {
// load list
List<Relation> relations = load();
// convert to tree
DefaultMutableTreeNode root = convertUsingObject(relations);
// logging
log(root);
// create ui
JTree tree = new JTree(root);
JScrollPane scrollPane = new JScrollPane(tree);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(300, 150);
frame.setVisible(true);
}
/**
* Load a relation list
* @return
*/
public static List<Relation> load() {
List<Relation> relations = new ArrayList<>();
relations.add(new Relation(null, 1));
relations.add(new Relation(1, 2));
relations.add(new Relation(1, 3));
relations.add(new Relation(2, 3));
relations.add(new Relation(3, 4));
return relations;
}
/**
* Convert the list to a tree using the relation object
* @param relations
* @return
*/
public static DefaultMutableTreeNode convertUsingObject(List<Relation> relations) {
// create a map of all possible tree node objects
Map<Relation,DefaultMutableTreeNode> nodeMap = new HashMap<>();
Map<Integer,DefaultMutableTreeNode> childNodeMap = new HashMap<>();
for(Relation relation: relations) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(relation);
nodeMap.put(relation, node);
childNodeMap.put(relation.child, node);
}
// create root
DefaultMutableTreeNode root = new DefaultMutableTreeNode(new Relation(null, null));
// iterate through all children, find the tree node and link the child to the parent
for(Relation relation: relations) {
DefaultMutableTreeNode node = nodeMap.get(relation);
if(relation.parent == null) {
root.add(node);
} else {
DefaultMutableTreeNode parent = childNodeMap.get(relation.parent);
parent.add(node);
}
}
return root;
}
/**
* Logging
* @param root
*/
public static void log(DefaultMutableTreeNode root) {
// log
Enumeration e = root.preorderEnumeration();
while (e.hasMoreElements()) {
System.out.println(e.nextElement());
}
}
/**
* Parent-child relationship
*/
public static class Relation {
Integer parent;
Integer child;
public Relation(Integer parent, Integer child) {
this.parent = parent;
this.child = child;
}
public String toString() {
return "" + child;
}
}
}
非常感謝您的幫助!
目前尚不清楚你在這裏試圖達到什麼目的。如果行'1 - > 3; 2 - > 3'表示創建了兩個不同的'Node 3'實例,然後您沒有問題,只有用於標識節點的「名稱」不是唯一的。這種解釋得到了這樣一個事實的支持,即這兩個實例可能有不同的子集。您還沒有告訴我們是否有多個屬性需要在多個名爲'3'的實例之間共享。這聽起來很像一個[XY問題](http://xyproblem.info)。請澄清你實際上試圖解決的問題。 –
我更新了問題。請注意,該列表是隨機順序,ID是隨機的。是的,必須創建2個不同的'Node 3'實例。但只有1個'Node 1'實例。 – Roland
還不清楚。你還有兩個不同的標有'4'的節點嗎? 「3 - > 4」行是否真的意思是「查找所有標記爲3的節點並添加標記爲4的子節點」? –