【问题标题】:How to find a distance between two node map<Integer,List<Integer>>如何找到两个节点之间的距离 map<Integer,List<Integer>>
【发布时间】:2015-09-18 10:45:26
【问题描述】:

在给定父子关系的情况下,我正在尝试编写一个程序来查找两个节点之间的距离

输入

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);
        }

【问题讨论】:

  • 如果你有一棵树,我会使用树数据结构来进行树操作。使思考更容易理解和编码。不过,您可以使用地图通过它们的 id 直接访问树节点。

标签: java algorithm data-structures solution


【解决方案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;

}

}

【讨论】:

    【解决方案2】:

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

    创建一个TreeNode 类型,它可以有TreeNode parent, List&lt;TreeNode&gt; children 属性。根节点parent为空,叶节点没有children

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

    【讨论】:

      【解决方案3】:

      虽然并非不可能,但我个人认为将地图导航为树的表示过于繁琐,最好是如上一个答案中所述的数据结构 - 对象具有其父级和子级的数据结构。

      计算它们之间的距离不是在寻找某些节点的同时遍历树的问题,如果您不了解树遍历,可以从这里开始https://en.wikipedia.org/wiki/Tree_traversal,但这并不难,只是还有更多的路要走通过它。

      【讨论】:

      • 上面的地图实现有没有办法找到高度
      【解决方案4】:

      我建议您使用简单的 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
      

      希望对您有所帮助。

      【讨论】:

      • 请检查您的推特帐户。
      • 请回复我的邮件
      猜你喜欢
      • 1970-01-01
      • 2014-05-04
      • 2022-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多