【问题标题】:Create all possible subtree of a tree in java在java中创建树的所有可能的子树
【发布时间】:2021-10-28 18:52:59
【问题描述】:

我有一个通用树,我想从中生成所有可能的子树。 示例(节点中的值是随机的):

          0 
        / | \ 
       1  2  4
          |  
          3          

可能的输出是:

(0)
(0,1)(0,2)(0,4)(0,2,3)
(0,1,2) (0,2,4) (0,1,2,3) (0,1,2,4) (0,2,3,4) 
(0,1,2,3,4)

我补充说我传递了一个包含节点和边列表的树对象,然后用 graphviz 打印。示例:

List<Node> nodes = new ArrayList<>(); // [0,1,2,3,4]
List<Edge> edges = new ArrayList<>(); // [(0,null), (0,1), (0,2), (2,3), (0,4)]

Tree tree = new Tree(nodes,edges); 
// this is an example of a tree that I pass as a parameter

我正在尝试使用递归方法,但我通过的边可以是随机的,节点也可以。我只知道根节点,它在第一条边[(0, null)]

提前感谢您的宝贵时间!

【问题讨论】:

    标签: java recursion tree graphviz


    【解决方案1】:

    我只在您的单个示例上对此进行了测试,但它似乎有效。

    public class Subtree
    {
        public static void main (String[] args)
        {
            Subtree app = new Subtree ();
            app.test ();
        }
    
        private void test ()
        {
            Node[] nodes = {new Node (0), new Node (1), new Node (2), new Node (3), new Node (4)};
            nodes[0].connect (nodes[1], nodes[2], nodes[4]);
            nodes[2].connect (nodes[3]);
    
            List<Node> result = subtrees (nodes[0], 0);
            for (Node tree : result)
            {
                System.out.printf ("Result Subtree %s %n", tree);
            }
        }
    
        private List<Node> subtrees (Node root, int traceLevel)
        {
            System.out.printf ("%s Subtrees from %s %n", "  |".repeat (traceLevel), root);
            List<Node> result = new ArrayList<> ();
            // Add a result for the root node with no children
            result.add (new Node (root.id));
            List<List<Node>> nextLevel = new ArrayList<> ();
            for (Node child : root.children)
            {
                // Form all subtrees of each direct child
                nextLevel.add (subtrees (child, traceLevel + 1));
            }
            result.addAll (formSubtrees (root.id, nextLevel, 0));
            System.out.printf ("%s => %s %n", "  |".repeat (traceLevel), result);
            return result;
        }
    
        private List<Node> formSubtrees (int rootId, List<List<Node>> nextLevel, int i)
        {
            List<Node> result = new ArrayList<> ();
            if (i < nextLevel.size ())
            {
                List<Node> remainder = formSubtrees (rootId, nextLevel, i + 1);
                for (Node n : nextLevel.get (i))
                {
                    Node t0 = new Node (rootId);
                    t0.connect (n);
                    result.add (t0);
                    for (Node r : remainder)
                    {
                        Node t = new Node (rootId);
                        t.connect (n);
                        for (Node c : r.children)
                        {
                            t.connect (c);
                        }
                        result.add (t);
                    }
                }
            }
            return result;
        }
    }
    
    class Node
    {
        int id;
    
        List<Node> children = new ArrayList<> ();
    
        Node (int id)
        {
            this.id = id;
        }
    
        public void connect (Node... nodes)
        {
            for (Node n : nodes)
            {
                children.add (n);
            }
        }
    
        public String toString ()
        {
            final StringBuilder buffer = new StringBuilder ();
            buffer.append ("[");
            buffer.append (getClass ().getSimpleName ());
            buffer.append (" ");
            buffer.append (id);
            for (Node n : children)
            {
                buffer.append (" ");
                buffer.append (n);
            }
            buffer.append ("]");
            return buffer.toString ();
        }
    }
    

    这是输出:

    = Subtrees from [Node 0 [Node 1] [Node 2 [Node 3]] [Node 4]] 
    =  | Subtrees from [Node 1] 
    =  | => [[Node 1]] 
    =  | Subtrees from [Node 2 [Node 3]] 
    =  |  | Subtrees from [Node 3] 
    =  |  | => [[Node 3]] 
    =  | => [[Node 2], [Node 2 [Node 3]]] 
    =  | Subtrees from [Node 4] 
    =  | => [[Node 4]] 
    = => [[Node 0], [Node 0 [Node 1]], [Node 0 [Node 1] [Node 2]], [Node 0 [Node 1] [Node 2] [Node 4]], [Node 0 [Node 1] [Node 2 [Node 3]]], [Node 0 [Node 1] [Node 2 [Node 3]] [Node 4]]] 
    Result Subtree [Node 0] 
    Result Subtree [Node 0 [Node 1]] 
    Result Subtree [Node 0 [Node 1] [Node 2]] 
    Result Subtree [Node 0 [Node 1] [Node 2] [Node 4]] 
    Result Subtree [Node 0 [Node 1] [Node 2 [Node 3]]] 
    Result Subtree [Node 0 [Node 1] [Node 2 [Node 3]] [Node 4]
    

    【讨论】:

    • 抱歉回复晚了,但我正在尝试自己解决问题。即使未生成以下边缘,您的代码也对我有所帮助:(0,2), (0,4), (0,2,3), (0,2,4), (0, 2,3,4 )。我通过在节点类中添加每个单个节点的所有子节点及其父节点的列表来改进我的代码,我正在寻找解决方案。无论如何,非常感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 2020-05-01
    • 1970-01-01
    相关资源
    最近更新 更多