Java数据结构与算法(无向图)

前言

图是一种用于表示对象及其相互关系的数据结构。图由顶点(也称为节点)和边组成,边连接顶点,表示顶点之间的关系。根据边的方向性,图可以分为有向图和无向图。根据边的权重,图可以分为加权图和非加权图。

实现原理

邻接表(Adjacency List)

  • 用一个数组或链表表示每个顶点的邻接顶点。
  • 每个顶点都有一个链表(或列表),存储其所有邻接顶点。
  • 优点:适合表示稀疏图,空间复杂度低,为 O(V+E)O(V + E)O(V+E),其中 VVV 是顶点数,EEE 是边数。
  • 缺点:查找两个顶点之间是否存在边的时间复杂度为 O(V)O(V)O(V)(链表实现)或 O(log⁡V)O(\log V)O(logV)(平衡树或哈希表实现)。

有一个简单的无向图

html 复制代码
A - B - C
|   |
D - E - F

动画过程

Depth-First Search Visualization

具体代码实现

java 复制代码
import java.util.*;

class Graph {
    private Map<String, List<String>> adjList;

    public Graph() {
        adjList = new HashMap<>();
    }

    // 添加边的方法
    public void addEdge(String v, String w) {
        adjList.putIfAbsent(v, new ArrayList<>());
        adjList.putIfAbsent(w, new ArrayList<>());
        adjList.get(v).add(w);
        adjList.get(w).add(v); // 无向图,双向添加
    }

    // 打印图的方法(可选,用于调试)
    public void printGraph() {
        for (String v : adjList.keySet()) {
            System.out.print(v + ": ");
            for (String w : adjList.get(v)) {
                System.out.print(w + " ");
            }
            System.out.println();
        }
    }

    // 递归实现深度优先搜索
    public void DFSRecursive(String start) {
        Set<String> visited = new HashSet<>();
        DFSUtil(start, visited);
    }

    private void DFSUtil(String v, Set<String> visited) {
        visited.add(v);
        System.out.print(v + " ");

        for (String neighbor : adjList.get(v)) {
            if (!visited.contains(neighbor)) {
                DFSUtil(neighbor, visited);
            }
        }
    }

    // 迭代实现深度优先搜索
    public void DFSIterative(String start) {
        Set<String> visited = new HashSet<>();
        Stack<String> stack = new Stack<>();
        stack.push(start);

        while (!stack.isEmpty()) {
            String v = stack.pop();
            if (!visited.contains(v)) {
                visited.add(v);
                System.out.print(v + " ");

                // 为了与递归实现顺序一致,反转邻接节点的顺序
                List<String> neighbors = adjList.get(v);
                Collections.reverse(neighbors);
                for (String neighbor : neighbors) {
                    if (!visited.contains(neighbor)) {
                        stack.push(neighbor);
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Graph g = new Graph();

        g.addEdge("A", "B");
        g.addEdge("A", "D");
        g.addEdge("B", "C");
        g.addEdge("B", "E");
        g.addEdge("D", "E");
        g.addEdge("E", "F");

        System.out.println("Graph representation:");
        g.printGraph();

        System.out.println("Depth First Traversal (Recursive) starting from node A:");
        g.DFSRecursive("A");
        System.out.println();

        System.out.println("Depth First Traversal (Iterative) starting from node A:");
        g.DFSIterative("A");
    }
}

QA:待定

相关推荐
奔跑吧邓邓子17 分钟前
【Java实战㉝】Spring Boot实战:从入门到自动配置的进阶之路
java·spring boot·实战·自动配置
ONLYOFFICE17 分钟前
【技术教程】如何将ONLYOFFICE文档集成到使用Spring Boot框架编写的Java Web应用程序中
java·spring boot·编辑器
叫我阿柒啊25 分钟前
Java全栈开发工程师的实战面试经历:从基础到微服务
java·微服务·typescript·vue·springboot·前端开发·后端开发
耶啵奶膘35 分钟前
uni-app头像叠加显示
开发语言·javascript·uni-app
看海天一色听风起雨落41 分钟前
Python学习之装饰器
开发语言·python·学习
cyforkk42 分钟前
Spring 异常处理器:从混乱到有序,优雅处理所有异常
java·后端·spring·mvc
Want5951 小时前
C/C++圣诞树①
c语言·开发语言·c++
生擒小朵拉1 小时前
STM32添加库函数
java·javascript·stm32
Z_z在努力1 小时前
【杂类】Spring 自动装配原理
java·spring·mybatis
老赵的博客1 小时前
c++ 杂记
开发语言·c++