如何在 Java 中实现图数据结构

发布:2024-09-14 14:05 阅读:15 点赞:0

本文将详细介绍如何在 Java 中实现图数据结构,特别是如何使用 HashMap 实现图的邻接表,并通过两个示例演示图的实现与操作。

一. 图的基本概念

图是一种数据结构,用于表示节点(顶点)之间的连接关系。图可以是有向图或无向图,节点可以有多个边连接。以下是图的一些基本概念:

  • 节点(Vertex):图中的基本元素,表示一个点。
  • 边(Edge):连接两个节点的线,表示两个节点之间的关系。
  • 邻接表(Adjacency List):一种图的表示方法,使用列表存储每个节点及其相邻节点。

二. 使用 HashMap 实现图的邻接表

1. 基本代码示例

以下是一个使用 HashMap 实现图的邻接表的示例代码:

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class Graph {
    // 定义图的邻接表,使用 HashMap 存储每个节点及其相邻节点
    private Map> adjacencyList;

    // 构造函数初始化邻接表
    public Graph() {
        adjacencyList = new HashMap<>();
    }

    // 添加一个节点到图中
    public void addVertex(int vertex) {
        adjacencyList.putIfAbsent(vertex, new HashSet<>());
    }

    // 添加一条边
    public void addEdge(int source, int destination) {
        adjacencyList.putIfAbsent(source, new HashSet<>());
        adjacencyList.putIfAbsent(destination, new HashSet<>());
        adjacencyList.get(source).add(destination);
        adjacencyList.get(destination).add(source); // 无向图
    }

    // 打印图的邻接表
    public void printGraph() {
        for (int vertex : adjacencyList.keySet()) {
            System.out.print(vertex + " -> ");
            for (int neighbor : adjacencyList.get(vertex)) {
                System.out.print(neighbor + " ");
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        // 创建一个图对象
        Graph graph = new Graph();
        
        // 添加节点
        graph.addVertex(1);
        graph.addVertex(2);
        graph.addVertex(3);
        graph.addVertex(4);
        graph.addVertex(5);
        
        // 添加边
        graph.addEdge(12);
        graph.addEdge(13);
        graph.addEdge(14);
        graph.addEdge(24);
        graph.addEdge(25);
        graph.addEdge(34);
        graph.addEdge(35);
        graph.addEdge(45);
        
        // 打印图的邻接表
        graph.printGraph();
    }
}

代码说明

  • import java.util.HashMap;:导入 HashMap 类,用于实现邻接表。

  • import java.util.HashSet;:导入 HashSet 类,用于存储每个节点的相邻节点。

  • import java.util.Map;:导入 Map 接口,用于定义邻接表的类型。

  • import java.util.Set;:导入 Set 接口,用于定义相邻节点的集合。

  • private Map> adjacencyList;:定义一个 HashMap 作为图的邻接表,其中每个节点(Integer 类型)映射到一个包含相邻节点的集合(Set 类型)。

  • public Graph():构造函数初始化邻接表。

  • public void addVertex(int vertex):向图中添加一个节点。如果节点不存在,则创建一个新的 HashSet 以存储相邻节点。

  • public void addEdge(int source, int destination):向图中添加一条边。如果源节点和目标节点不存在,则创建它们;否则,将目标节点添加到源节点的邻接列表中,并将源节点添加到目标节点的邻接列表中(无向图)。

  • public void printGraph():打印图的邻接表。遍历每个节点及其相邻节点,并输出结果。

  • public static void main(String[] args):主函数用于测试图的创建、节点和边的添加以及邻接表的打印。

三. 使用类封装边信息

在这个示例中,我们将图的边信息封装到一个 Edge 类中,并演示如何在图中管理和显示这些边。

1. 基本代码示例

以下是一个封装边信息的图实现示例:

public class Graph {
    // 内部类 Edge 用于存储边的信息
    class Edge {
        int source, destination;
    }
    
    int vertices, edges; // 节点数和边数
    Edge[] edge; // 存储边的数组

    // 构造函数初始化图的边
    Graph(int vertices, int edges) {
        this.vertices = vertices;
        this.edges = edges;
        edge = new Edge[edges];
        for (int i = 0; i < edges; i++) {
            edge[i] = new Edge();
        }
    }

    // 打印图的边信息
    static void print(Graph graph_object, int edges_count) {
        System.out.println("图的边连接关系为:");
        for (int i = 0; i < edges_count; i++) {
            System.out.println(graph_object.edge[i].source + " - " + graph_object.edge[i].destination);
        }
    }

    // 连接图的边
    static void connect_edges(Graph graph_object) {
        graph_object.edge[0].source = 1;
        graph_object.edge[0].destination = 2;
        graph_object.edge[1].source = 1;
        graph_object.edge[1].destination = 3;
        graph_object.edge[2].source = 1;
        graph_object.edge[2].destination = 4;
        graph_object.edge[3].source = 2;
        graph_object.edge[3].destination = 4;
        graph_object.edge[4].source = 2;
        graph_object.edge[4].destination = 5;
        graph_object.edge[5].source = 3;
        graph_object.edge[5].destination = 4;
        graph_object.edge[6].source = 3;
        graph_object.edge[6].destination = 5;
        graph_object.edge[7].source = 4;
        graph_object.edge[7].destination = 5;
    }

    public static void main(String[] args) {
        int vertices_count = 5;
        int edges_count = 8;
        Graph graph_object = new Graph(vertices_count, edges_count);
        System.out.println("图对象已定义。");
        connect_edges(graph_object);
        print(graph_object, edges_count);
    }
}

代码说明

  • class Edge:定义一个内部类 Edge,用于存储边的源节点和目标节点。

  • Graph(int vertices, int edges):构造函数初始化图的节点数和边数,并创建一个 Edge 类型的数组来存储边。

  • static void print(Graph graph_object, int edges_count):静态方法用于打印图的边信息。

  • static void connect_edges(Graph graph_object):静态方法用于连接图的边,手动设置每条边的源节点和目标节点。

  • public static void main(String[] args):主函数用于测试图的创建、边的连接以及边信息的打印。

通过以上两个示例,我们展示了如何在 Java 中实现图的数据结构。使用 HashMap 可以高效地表示和操作图的邻接表,而通过封装边信息的方式可以使图的边管理更加直观。