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:待定

相关推荐
慕y27410 分钟前
Java学习第九十三部分——RestTemplate
java·开发语言·学习
上单带刀不带妹12 分钟前
JavaScript 中的宏任务与微任务
开发语言·前端·javascript·ecmascript·宏任务·微任务
旋风菠萝13 分钟前
设计模式---单例
android·java·开发语言
啊呦.超能力22 分钟前
QT开发---图形与图像(补充)
开发语言·qt
郝学胜-神的一滴34 分钟前
应用Builder模式在C++中进行复杂对象构建
开发语言·c++·程序人生
AI视觉网奇40 分钟前
音频获取长度
java·前端·python
微露清风41 分钟前
C语言习题讲解-第九讲- 常见错误分类等
c语言·开发语言
FC_nian1 小时前
IDEA配置(Maven)
java·maven·intellij-idea
寄思~1 小时前
学习笔记:封装和单继承
开发语言·笔记·python·学习
归云鹤1 小时前
C++ 构造函数语义学
开发语言·c++