建立叶子的地图 - 成对的祖先列表(父 - 子)

时间:2015-09-09 13:59:12

标签: java algorithm tree

我有一个树形结构,我需要以地图的形式表示,关键是叶子和叶子的祖先列表的值(祖先的顺序并不重要)。

例如,像这样的树:

      1
     / \
    2   3
   / \
  4   5
 /
6

会像这样结束:

6 -> [4, 2, 1]
5 -> [2, 1]
3 -> [1]

要构建此地图,我会收到一对(父,子)对的列表。

对于示例树,我将按顺序给出:

1, 2
1, 3
2, 4
2, 5
4, 6

更好地理解的执行示例:

首先,地图为空。我得到2,4。

地图包含4 - > [2]。我得到了2,5。

地图包含4 - > [2],5 - > [2]。我给了4,6。

地图包含6 - > [4,2],5 - > [2]。我给了1,3。

地图包含6 - > [4,2],5 - > [2],3 - > [1]。我被给予1,2。

地图包含6 - > [4,2,1],5 - > [2,1],3 - > [1]。

我想出了一些东西,但感觉臃肿而难以理解。 某些特定的输入顺序也是错误的:

1, 3
4, 6
1, 2
2, 4
2, 5

产量

6 -> [4, 2, 1]
5 -> [4, 2, 1]
3 -> [1]

代码:

updateMap(long parent, long child) {
    if (map.isEmpty()) {
        map.put(child, Sets.newHashSet(parent));
    } else {
        Set<Long> flattenedValues = new HashSet<Long>();
        for (Set<Long> set : map.values()) {
            flattenedValues.addAll(set);
        }
        if (flattenedValues.contains(child)) {
            for (Long key : getKeysByValue(map, child)) {
                map.get(key).add(parent);
            }
            if (map.containsKey(parent)) {
                for (Long key : getKeysByValue(map, parent)) {
                    Set<Long> toAdd = new HashSet<Long>();
                    toAdd.add(parent);
                    toAdd.addAll(map.remove(parent));
                    map.get(key).addAll(toAdd);
                }
            }
        } else {
            if (map.containsKey(parent)) {
                map.put(child, Sets.newHashSet(parent));
                map.get(child).addAll(
                        map.remove(parent));
            } else {
                map.put(child, Sets.newHashSet(parent));
                for (Long key : getKeysByValue(map, parent)) {
                    map.get(child).addAll(map.get(key));
                }
            }
        }
    }
}

我相信有更好的方法可以做我想做的事,你能帮助我吗?谢谢!

1 个答案:

答案 0 :(得分:1)

使用数组可以很容易地解决这个问题。将会有2个非常有用的数组。

isLeaf :此数组将存储布尔值,并将告知节点是否为leaf。最初所有值都是真的。

每当输入一对时,第一个元素的值设置为false,因为它有一个子元素。

parent :此数组将存储节点父节点的值。最初所有值都设置为-1,每当输入一对时,就会设置该对的第二个元素的父值第一元素。

基本理念:解决这个问题的想法非常简单和优雅。

基本上我们遍历节点,对于所有叶子节点,我们使用父数组列出他们的祖先,终止条件也非常简单,因为只有当我们到达根时才会停止设置为-1

import java.util.*;
class Tree
{
 public static void main(String []args)
 {
     int n,i,p,j,c,pairs;
     Scanner sc=new Scanner(System.in);
     System.out.println("enter the number of elements in tree");
     n=sc.nextInt();
     boolean []isLeaf=new boolean[n];
     int []parent=new int[n];     
     for(i=0;i<n;++i)
     {
          isLeaf[i]=true;
          parent[i]=-1;
     }
     System.out.println("Enter the number of  pairs");
     pairs=sc.nextInt();
     System.out.println("now enter pairs like 1 2(separate them by space)");
     for(i=0;i<pairs;++i)
     {
         p=sc.nextInt();
         c=sc.nextInt();
         isLeaf[p-1]=false;
         parent[c-1]=p-1;
     }     
     for(i=0;i<n;++i)
      if(isLeaf[i])
      {
          j=i;
          System.out.println("\nthe ancestors of "+(i+1)+" are");
          while(parent[j]!=-1)
           {System.out.print((parent[j]+1)+" ");j=parent[j];}
      }
 }
}