如何在两个节点映射<integer,list <integer>&gt;

时间:2015-09-18 10:45:27

标签: java algorithm data-structures solution

我正在尝试制作一个程序来找到两个节点之间的距离,给定父子关系

输入

1 2

1 3

3 4

3 5  

我使用以下代码来获取值。树是双向的,并且与每个节点具有单位距离。

代码

    Map<Integer, List<Integer>> adjacencies = new HashMap<Integer,  List<Integer>>(); 
        for (int i=1; i<=n; i++) {
           List<Integer> l1= new ArrayList<Integer>();
           adjacencies.put(i,l1);
        }  
        for (int i=0; i<n-1; i++) {
            int u = in.nextInt();
            int v = in.nextInt();
            adjacencies.get(u).add(v);
            adjacencies.get(v).add(u);
        }

4 个答案:

答案 0 :(得分:1)

您可以使用BFS查找两个节点之间的距离。我希望这个解决方案可以帮到你。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;

public class StackOverFlow {
static Map<Integer, List<Integer>> adjacencies = new HashMap<Integer, List<Integer>>(); 

public static void main(String[] args) {

    Scanner in = new Scanner(System.in);
    int n = in.nextInt();

    for (int i=1; i<=n; i++) {
       List<Integer> l1= new ArrayList<Integer>();
       adjacencies.put(i,l1);
    }  
    for (int i=0; i<n-1; i++) {
        int u = in.nextInt();
        int v = in.nextInt();
        adjacencies.get(u).add(v);
        adjacencies.get(v).add(u);
    }

    findingDistanceBetweenTwoNodes(1, 3);
}
static int [] parent = new int[100];
static boolean [] visited = new boolean[100];

public static void findingDistanceBetweenTwoNodes(int nodea, int nodeb){

    Queue<Integer> q = new LinkedList<Integer>();
    q.add(nodea);
    parent[nodea] = -1;
    visited[nodea] = true;
    boolean loop = true;
    while(!q.isEmpty() && loop){
        int element = q.remove();
        Integer s =null;

        while((s = getChild(element))!=null) {
            parent[s] = element;
            visited[s] = true;
            if(s == nodeb)
            {
                loop= false;
                break;
            }

            q.add(s);
        }
    }
    int x = nodeb;
    int d = 0;
    if(!loop)
     {
        while(parent[x] != -1)

     {
         d +=1;
         x = parent[x];
     }

    System.out.println("\nThe distance from node "+nodea+ " to node "+nodeb+" is "   +d);
     }
    else
        System.out.println("Can't reach node "+nodeb);
}


private static Integer getChild(int element) {
    ArrayList<Integer> childs = (ArrayList<Integer>) adjacencies.get(element);
    for (int i = 0; i < childs.size(); i++) {
        if(!visited[childs.get(i)])
        return childs.get(i);
    }
    return null;

}

}

答案 1 :(得分:0)

假设一个节点只能有一个父节点。

创建TreeNode类型,它可以具有TreeNode parent, List<TreeNode> children个属性。根节点parent为空,叶节点没有children

我认为这种树形结构使您的工作更轻松。

答案 2 :(得分:0)

虽然并非不可能,但我个人认为导航Map作为树的表示过于繁琐,最好的是前面回答中描述的数据结构 - 一个对象有父对象和子对象的对象。

计算它们之间的距离不是在寻找某些节点时遍历树的问题,如果你不知道树遍历,你可以从这里开始https://en.wikipedia.org/wiki/Tree_traversal,但这并不困难,只有更多的方法通过它。

答案 3 :(得分:0)

我建议你用一个简单的DFS程序来做,因为它更容易编码,并且不需要额外的内存(超出递归堆栈),只要时间复杂度是可以接受的:

int dfs(int u, int pu, int target, int h, Map<Integer, List<Integer>> adjacencies) {
    if (u == target) { // if target reached
      return h; // return current distance
    }
    for (int v : adjacencies.get(u)) {
      if (v != pu) { // don't go up in the tree, only down
        int d = dfs(v, u, target, h+1, adjacencies);
        if (d != -1) { // if target is in this subtree
          return d;
        }
      }
    }
    return -1; // target is not in this subtree
  }

您可以像以下一样使用它:

int from = 1;
int to = 5;
int dist = dfs(from, -1, to, 0, adjacencies); // use from as root of DFS

希望它有所帮助。