我有一个List,其中包含数据库中的一些表,其中每行包含一个引用另一行的父字段。喜欢这个
标题,父母 A,null
B,A
C,A
D,C
E,B
F,null
这里A和F是根节点,B和C是A的子节点,D是C的子节点,E依次是B节的子节点。
从此列表中生成树结构的最佳方法是什么?
一种方法是在查找根(没有父母的标题)的列表上进行递归,然后对每个根再次循环遍历列表并附加根节点。然后,对于那些节点,再次遍历完整列表以附加他们自己的任何子节点。
示例:
private Node getNode(SomeData d) {
List<SomeData> tmp = getChildren(d);
if (tmp == null OR empty) return new Node(d);
Node n = new Node(d);
for (SomeData m : tmp) {
n.addChild(getNode(m)); // recurse
}
return n;
}
private List<SomeData> getChildren(SomeData parent) {
List<SomeData> tmp = new ArrayList<SomeData>();
for (SomeData candidateChild : myBigFlatDataList.values()) {
if (parent.equals(candidateChild)) {
tmp.add(candidateChild);
}
}
return tmp;
}
有更好的方法吗?
答案 0 :(得分:1)
由于您从数据库获取数据,因此可以根据父属性对行进行排序。然后,每次搜索节点的子节点时,您都不需要遍历整个列表。
修改强> 列表排序后,当您找到所有要查找的子项时,可以停止遍历列表。例如,当您拥有根“A”并开始在此列表中搜索其子项时:
B, A
C, A
E, B <- when you reach "B" you can assume that there are no
D, C other nodes which are children of "A" and stop the iteration
答案 1 :(得分:1)
为每个节点重新读取整个文件(或者更糟糕的是查询数据库)是相当昂贵的。我希望你在阅读列表时构建树。这是我的2美分
如果你遵循这个,在迭代结束时你应该有:
RootNodes = {A,F}
Nodes = {B,C,D,E}
A.child = B
A.child = C
C.child = D
B.child = E
希望这有帮助。
答案 2 :(得分:1)
您可以一次构建树。您可以对表进行第一次传递以构建所有节点(从名称到节点构建哈希表),然后执行另一个传递,您可以在其中添加两个节点之间的父子关系(将父指针添加到子节点并将子节点添加到父母的孩子名单。)
答案 3 :(得分:1)
这是一个非常好的方式,但它比它必须更天真。
另一条路线只需要线性时间。 SomeData是否有一些唯一标识它的东西?我会这么认为;这可能是SomeData本身正确实现equals()和hashCode()。
让我们说方法int SomeData.getID()
。然后我们可以保留我们之前在HashMap中看到的节点。
Map<Integer, Node> visitedNodes = new HashMap...
然后我们只是通过行阅读:
for ( SomeData data : ... ) {
SomeData parent = data.getParent();
Node<SomeData> parentNode = getOrCreateNode(parent);
Node<SomeData> childNode = getOrCreateNode(data);
parentNode.addChild(childNode);
}
private Node<SomeData> getOrCreateNode(SomeData data) {
Node<SomeData> node = visitedNodes.get(data.getID());
if ( node == null ) {
node = new Node<SomeData>(data);
visitedNodes.put(data.getID(), node);
}
return node;
}
答案 4 :(得分:1)
List<User> list = new ArrayList<User>();
User blankNode;
class User{
String userid;
User child;
public User() {
//blankNode
}
public User(String userid) {
this.userid = userid;
}
@Override
public int hashCode(){
return userid.hashCode();
}
}
public void addUser(User parent,String userid){
if(null == userid)return;
User child = new User(userid);
parent.child = child;
list.add(child);
}
public void removeUser(User child){
if(null == child)return;
list.remove(child);
}
/* move the rank to up - assume
* secParent - assign to new child
*/
public void boubbleUp(User secParent, User oldParent, User child){
if(null == child || null == secParent)return;
secParent.child = child;
oldParent.child = null;
}
public List<User> getTopUser(int num){
if(num <1)return null;
Map<Integer, List<User>> map = new HashMap<Integer, List<User>>();
for(User usr : list){
int count =0;
User temp = usr.child;
while(null != temp){
count++;temp=temp.child;
}
if(map.get(count)== null){
List<User> sameNoOfChildren = new ArrayList<User>() ;
sameNoOfChildren.add(usr);
map.put(count, sameNoOfChildren);
}else{
map.get(count).add(usr);
}
}
Integer[] arr = (Integer[]) map.keySet().toArray();
Arrays.sort(arr);
List<User> result = new ArrayList<User>();
for(int i = arr.length-1; i <=arr.length-num; i-- ){
result.addAll(map.get(i));
}
return result;
}