Java:从对列表中构造一个树(具有重复节点)

时间:2016-10-25 11:55:39

标签: java tree nodes

我想从对列表中构造一个树。
对以下列方式表示:子节点/父节点。
示例:
2177/2178
2157/2178
2179/2177
2177/2157
2500/2177

在这些对中,我想构建以下树:

              2500        
                /
2179        2177
    \         /
   2177   2157
       \    /
        2178    

我知道当所有节点都有不同的值时,这是可能的。但是,如果节点可以具有重复值(如此示例中)吗?

2 个答案:

答案 0 :(得分:0)

如果你的目的只是建造一棵树,你可以使用这样的东西。它保留了节点地图(映射“上一个”),因为没有订单信息可供使用。请注意,构建的树不是单义的:

package org.norsam;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author samuele m.
 *
 */
public class Mu
{

    // nodes with that value
    private Map<Integer, Set<TItem>> previous = new HashMap<>();

    private TItem root = null;

    public void addItem(Integer child, Integer parent)
    {
        // find a parent
        TItem tparent = findAParentLike(parent);
        // create child and add it to the parent
        TItem titem = new TItem(child);
        tparent.addChildren(titem);
        // add children to the map of "existent" elements
        if (!previous.containsKey(child)) {
            previous.put(child, new HashSet<TItem>());
        }
        previous.get(child).add(titem);
    }

    /**
     * Which node has this value?
     *
     * @param parent
     */
    private TItem findAParentLike(Integer parent)
    {
        if (root == null) {
            root = new TItem(parent);
            previous.put(parent, new HashSet<TItem>());
            previous.get(parent).add(root);
            return root;
        }
        if (!previous.containsKey(parent)) {
            throw new RuntimeException("Node " + parent + " not found");
        }
        Set<TItem> elems = previous.get(parent);
        return elems.iterator().next(); // one "random"
    }

    public void visit()
    {
        visit(root, ""+root.value);
    }

    private void visit(TItem elem, String base)
    {
        for (Integer child : elem.children.keySet()) {
            System.out.println(base + ":" + child.intValue());
            for (TItem item : elem.children.get(child)) {
                visit(item, base + ":" + child.intValue());
            }
        }
    }

    public static void main(String[] args)
    {
        Mu mu = new Mu();
        mu.addItem(2, 1);
        mu.addItem(3, 2);
        mu.addItem(4, 3);
        mu.addItem(4, 2);
        mu.addItem(5, 4);
        mu.addItem(6, 4);
        mu.addItem(5, 4);
        mu.addItem(6, 2);
        mu.addItem(7, 6);
        mu.addItem(9, 1);

        mu.visit();
    }
}

class TItem
{
    public int value;
    public Map<Integer, Set<TItem>> children = new HashMap<>(0);

    TItem()
    {
    }

    TItem(int value)
    {
        this.value = value;
    }

    void addChildren(TItem titem)
    {
        if (!children.containsKey(titem.value)) {
            children.put(titem.value, new HashSet<TItem>());
        }
        children.get(titem.value).add(titem);
    }
}

使用以下输出(在我的笔记本电脑上):

1:2
1:2:4
1:2:6
1:2:6:7
1:2:3
1:2:3:4
1:2:3:4:6
1:2:3:4:5
1:9

或另一个,相当于前一个:

1:2
1:2:4
1:2:6
1:2:3
1:2:3:4
1:2:3:4:6
1:2:3:4:6:7
1:2:3:4:5
1:9

答案 1 :(得分:-1)

您可以将Set个父母作为值,而不是单个值,或使用Apache的MultiHashMap