图的Hashmap表示

use*_*119 5 java graph hashmap

例如,我有一个带图形边的文本文件

1 2

1 3

2 5

等,并希望以某种方式表示我的图表.我试图使用hashmap,它是表示边缘的最佳方式吗?第二个问题,我如何访问我的hashmap中的第一个和第二个条目?我的代码在这里

    DataInputStream dStream = new DataInputStream(new FileInputStream("C:/Programming/Java/test.txt"));
    BufferedReader bReader = new BufferedReader(new InputStreamReader(dStream));

    HashMap<Integer, Integer> graphEdges = new HashMap<Integer, Integer>();
    String line;
    while( (line = bReader.readLine()) != null) {
        String[] firstSecond = line.split(" ");
        int firstDigit = Integer.parseInt(firstSecond[0]);
        int secondDigit = Integer.parseInt(firstSecond[1]);

        graphEdges.put(firstDigit, secondDigit);
    }

    System.out.println(graphEdges);

    bReader.close();
}
Run Code Online (Sandbox Code Playgroud)

Dim*_*mos 7

在图的许多可能表示中,2基本如下:

  • 邻接列表

在此输入图像描述

在Java中:

Map<Integer, List<Integer>> graph = new HashMap<>();
...
while( (line = bReader.readLine()) != null) {
    String[] tokens = line.split(" ");
    int firstNode = Integer.parseInt(tokens[0]);
    int secondNode = Integer.parseInt(tokens[1]);

    if(!graph.containsKey(firstNode)) graph.put(firstNode, new LinkedList());
    graphEdges.get(firstNode).add(secondNode);
}
Run Code Online (Sandbox Code Playgroud)
  • 邻接矩阵

在此输入图像描述

在Java中:

int[][] graph = new int[numberOfNodes][numberOfNodes];
while( (line = bReader.readLine()) != null) {
    String[] tokens = line.split(" ");
    int firstNode = Integer.parseInt(tokens[0]);
    int secondNode = Integer.parseInt(tokens[1]);

    graph[firstNode-1][secondNode-1] = 1;
    graph[secondNode-1][firstNode-1] = 1;
}
Run Code Online (Sandbox Code Playgroud)

以下是这两种表示的操作和存储效率的比较:

                   |     Adjacency List    |   Adjacency Matrix   |
Storage            |      O(nodes+edges)   |     O(nodes^2)       |
Add node           |          O(1)         |     O(nodes^2)*      |
Add edge           |          O(1)         |        O(1)          |
Remove node        |        O(edges)       |     O(nodes^2)*      |
Remove edge        |        O(edges)       |        O(1)          |
isAdjacent(x1,x2)  |        O(nodes)       |        O(1)          |
*Requires copying of the whole array
Run Code Online (Sandbox Code Playgroud)

您还可以在邻接列表中稍作修改,并使用HashSets而不是LinkedList来存储相邻节点.在这种情况下,除了isAdjacent(x1,x2)操作现在具有O(1)复杂度(摊销)之外,一切都是相同的.


dan*_*dan 3

AHashMap不适合这种情况,因为对于指定的键,您可以有一个值。您需要一个可以保存一个键的多个值的映射。Guava在Multimap中正是具有这个概念,并具有ArrayListMultimap之类的实现。

  • +1。即使没有 Guava,也可以使用“Map&lt;Integer, List&lt;Integer&gt;&gt;”。 (3认同)
  • @JB Nizet 或 `Map&lt;Integer, Set&lt;Integer&gt;&gt;` (3认同)