用Java高效地表示图形

用Java高效地表示图形,java,graph,Java,Graph,在许多在线资源和教科书中,他们说图形表示为: 每个节点存储其邻居的列表: 类图{ ArrayList所有节点 class Node{ Integer id; ArrayList<Node> neighbors; Boolean visited; } 类节点{ 整数id; ArrayList邻居; 参观; } 或具有邻接列表,如下所示: class Graph{ HashMap<Node,ArrayList<Node>> adjMap; }

在许多在线资源和教科书中,他们说图形表示为:

  • 每个节点存储其邻居的列表:

    类图{ ArrayList所有节点

    class Node{
     Integer id;
     ArrayList<Node> neighbors;
     Boolean visited;
     }
    
    类节点{
    整数id;
    ArrayList邻居;
    参观;
    }
    
  • 或具有邻接列表,如下所示:

    class Graph{
       HashMap<Node,ArrayList<Node>> adjMap;
    }
    
    class Node{
        Integer id;
        Boolean visited;
    }
    
    类图{
    HashMap;
    }
    类节点{
    整数id;
    参观;
    }
    
  • 这些不同的在线资源声称我们可以添加一个布尔标志来跟踪访问的节点。我认为C++对指针是可以的,但是它在java中不起作用。我的问题是在实现BFS、DFS、Topological Sort和使用修改的DFS检测周期时,我发现java中的上述方法不起作用。在k个访问节点中,您向类节点添加了一个布尔标志“已访问”。但该标志在整个图中不一致。为了举例说明,假设我们有一个图,上面的(1)表示为:

    <Node> => ArrayList<nighbors>
    1 => 2 , 3, 5
    2 => 4
    3 => 4, 5
    
    =>数组列表
    1 => 2 , 3, 5
    2 => 4
    3 => 4, 5
    
    当从文件填充此图时,我发现Java对待节点2指向的节点4与节点3指向的节点4不同。尽管重写了equals()和hashCode()方法,这一点仍然存在。 类似地,如果将图表示为上面的(2),则当访问节点3时再次遇到节点4时,不会记住在其邻居的ArrayList中多次包含节点4并在访问节点2时修改节点4的已访问标志的adjMap

    我找到的解决方案是这样表示的图形:

    class Graph{
     public class Graph {
        // Graph is shown as Node -> List of neighbouring nodes
        HashMap<Node, ArrayList<Node>> adjMap = new HashMap<Node, ArrayList<Node>>();
        HashMap<Node, Boolean> isExploredMap = new HashMap<Node, Boolean>();
        Set<Node> allNodes = new HashSet<Node> ();
    }
    
    class Node{
     Integer id;
    }
    
    类图{
    公共类图{
    //图形显示为节点->相邻节点列表
    HashMap adjMap=新的HashMap();
    HashMap isExploredMap=新HashMap();
    Set allNodes=newhashset();
    }
    类节点{
    整数id;
    }
    
    也就是说,我们保留另一个名为isExploredMap的HashMap,用于存储节点是否被访问。我关心的是,它需要更多的O(N)空间,这与前两个建议的解决方案不同,这两个解决方案对我不起作用。有人能解释一下如何获得前两个解决方案以克服不一致的标志条件吗? 或者,如果这不可能,我需要确认我的解决方案是做这些事情的一种可接受的方式

    这是假设输入是从以每行为边的文件读取的,例如: 1 2 2 3 14


    指示节点1连接到节点2和节点4,节点2连接到节点3

    从文件填充此图时,我发现Java将节点2指向的节点4与节点3指向的节点4视为不同。
    -对不起,什么?您可能正在创建另一个对象,而该节点实际上并不相同。Cor但是如果我们不创建另一个对象,那么当我们再次遇到数字4时,如何在不创建新节点的情况下存储它(4)?
    从文件填充此图时,我发现Java将节点2指向的节点4与节点3指向的节点4视为不同。
    -对不起,什么?您可能正在创建另一个对象,而该节点实际上并不相同。正确,但如果我们不创建另一个对象,则在遇到获得数字4,如何在不创建新节点(4)的情况下存储它?