news 2026/9/4 8:35:44

【数据结构】图的数据结构核心知识点与代码实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【数据结构】图的数据结构核心知识点与代码实现

数据结构“图”章节核心知识点与代码实现

一、 图的基础知识点

知识点核心内容
图的定义G(V, E)顶点集合 V边集合 E组成,用于表示多对多关系。
图的分类1. 有向图 vs 无向图:边是否有方向。
2. 带权图 vs 无权图:边是否有权重。
3. 连通图 vs 非连通图:任意两顶点间是否有路径。
图的存储结构1. 邻接矩阵:二维数组,适合稠密图,查询边快O(1)
2. 邻接表:数组+链表,适合稀疏图,节省空间。
3. 邻接多重表/十字链表:用于优化特定操作。
图的遍历算法1. 深度优先搜索 (DFS):递归或栈实现,探索图的深度。
2. 广度优先搜索 (BFS):队列实现,探索图的广度。
图的应用算法1. 最短路径:Dijkstra(单源,无负权)、Floyd(多源)。
2. 最小生成树:Prim(加点法)、Kruskal(加边法)。
3. 拓扑排序:用于有向无环图 (DAG) 的任务排序。
4. 关键路径:AOE网中决定项目工期的路径。

二、 核心代码段(Java实现)

1. 图的邻接表表示与DFS/BFS遍历

import java.util.*; // 使用邻接表表示无向图 class Graph { private int V; // 顶点数 private LinkedList<Integer> adj[]; // 邻接表 // 构造函数 Graph(int v) { V = v; adj = new LinkedList[v]; for (int i = 0; i < v; ++i) { adj[i] = new LinkedList<>(); } } // 添加边(无向图) void addEdge(int v, int w) { adj[v].add(w); adj[w].add(v); // 有向图则注释此行 } //深度优先搜索 (DFS) 递归实现 void DFSUtil(int v, boolean visited[]) { visited[v] = true; // 标记当前节点为已访问 System.out.print(v + " "); // 递归访问所有未访问的邻接顶点 for (int n : adj[v]) { if (!visited[n]) { DFSUtil(n, visited); } } } void DFS(int v) { boolean visited[] = new boolean[V]; DFSUtil(v, visited); } // 广度优先搜索 (BFS) 队列实现 void BFS(int s) { boolean visited[] = new boolean[V]; LinkedList<Integer> queue = new LinkedList<>(); visited[s] = true; queue.add(s); while (!queue.isEmpty()) { s = queue.poll(); // 从队列头部取出顶点 System.out.print(s + " "); // 将该顶点的所有未访问邻接点入队 for (int n : adj[s]) { if (!visited[n]) { visited[n] = true; queue.add(n); } } } } } public class Main { public static void main(String args[]) { Graph g = new Graph(4); g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(1, 2); g.addEdge(2, 3); System.out.println("从顶点0开始的深度优先遍历:"); g.DFS(0); // 输出: 0 1 2 3 System.out.println(" 从顶点0开始的广度优先遍历:"); g.BFS(0); // 输出: 0 1 2 3 } }

2. Dijkstra算法求单源最短路径(邻接矩阵,无负权)

import java.util.*; class DijkstraAlgorithm { // 辅助方法:找到未处理顶点中距离最小的顶点索引 int minDistance(int dist[], Boolean sptSet[], int V) { int min = Integer.MAX_VALUE, minIndex = -1; for (int v = 0; v < V; v++) { if (!sptSet[v] && dist[v] <= min) { min = dist[v]; minIndex = v; } } return minIndex; } // 打印最短路径结果 void printSolution(int dist[], int V) { System.out.println("顶点 \t距源点距离"); for (int i = 0; i < V; i++) { System.out.println(i + " \t\t " + dist[i]); } } // Dijkstra算法核心实现 void dijkstra(int graph[][], int src, int V) { int dist[] = new int[V]; // 存储源点到各点的最短距离 Boolean sptSet[] = new Boolean[V]; // 标记顶点是否已处理 // 初始化:距离设为无穷大,集合设为空 for (int i = 0; i < V; i++) { dist[i] = Integer.MAX_VALUE; sptSet[i] = false; } dist[src] = 0; // 源点到自身的距离为0 // 循环 V-1 次,每次确定一个顶点的最短路径 for (int count = 0; count < V - 1; count++) { // 选取未处理顶点中距离最小的顶点u int u = minDistance(dist, sptSet, V); sptSet[u] = true; // 标记为已处理 // 更新u的所有邻接顶点的距离 for (int v = 0; v < V; v++) { // 更新条件:1.边存在2.未处理 3.新路径更短 if (!sptSet[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v]; } } } printSolution(dist, V); } public static void main(String[] args) { int V = 5; // 顶点数 int graph[][] = new int[][] { { 0, 10, 0, 0, 5 }, // 邻接矩阵,0表示无边 { 10, 0, 1, 0, 2 }, { 0, 1, 0, 4, 0 }, { 0, 0, 4, 0, 3 }, { 5, 2, 0, 3, 0 } }; DijkstraAlgorithm t = new DijkstraAlgorithm(); System.out.println("Dijkstra算法结果(源点为顶点0):"); t.dijkstra(graph, 0, V); } }

3. 拓扑排序(基于BFS的Kahn算法)

import java.util.*; class TopologicalSort { private int V; // 顶点数 private LinkedList<Integer> adj[]; // 邻接表 TopologicalSort(int v) { V = v; adj = new LinkedList[v]; for (int i = 0; i < v; ++i) { adj[i] = new LinkedList<>(); } } // 添加有向边 v -> w void addEdge(int v, int w) { adj[v].add(w); } // 拓扑排序主函数 void topologicalSort() { int indegree[] = new int[V]; // 存储每个顶点的入度 // 计算所有顶点的入度 for (int i = 0; i < V; i++) { for (int node : adj[i]) { indegree[node]++; } } Queue<Integer> queue = new LinkedList<>(); // 将所有入度为0的顶点加入队列 for (int i = 0; i < V; i++) { if (indegree[i] == 0) { queue.add(i); } } int cnt = 0; // 记录已输出的顶点数 List<Integer> topOrder = new ArrayList<>(); while (!queue.isEmpty()) { int u = queue.poll(); topOrder.add(u); // 遍历u的所有邻接点,将其入度减1 for (int node : adj[u]) { // 如果入度减为0,则加入队列 if (--indegree[node] == 0) { queue.add(node); } } cnt++; } // 检查是否存在环 if (cnt != V) { System.out.println("图中存在环,无法进行拓扑排序"); return; } // 输出拓扑排序结果 System.out.println("拓扑排序结果:"); for (int i : topOrder) { System.out.print(i + " "); } } public static void main(String args[]) { TopologicalSort g = new TopologicalSort(6); g.addEdge(5, 2); g.addEdge(5, 0); g.addEdge(4, 0); g.addEdge(4, 1); g.addEdge(2, 3); g.addEdge(3, 1); g.topologicalSort(); // 一种可能输出: 5 4 2 3 1 0 } }

参考来源

  • 计算机类本科毕业设计论文大纲设计及论文撰写指南
  • Java期末复习题详解
  • Java毕业设计基于Vue+SpringBoot企业个性化展示平台(代码+数据库+文档LW+运行成功)
  • 写作经验分享【29】目标检测硕士论文从开题到答辩的模块化写作指南【持续更新】
  • AI提示词实战指南:从核心心法到结构化模板,提升大模型协作效率
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 8:34:37

基于EG8030的三相两电平逆变器设计与SPWM调制实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 8:27:42

黑烟车智能识别系统:从林格曼黑度检测到执法证据链生成

简介&#xff1a;本资源是一套面向本科生毕业设计与课程实践的黑烟车智能识别系统完整实现方案&#xff0c;聚焦环境监测场景下的计算机视觉应用&#xff0c;解决机动车尾气污染监管中的自动化识别难题。资源包共2000个文件&#xff0c;含491张标注图像&#xff08;jpg&#xf…

作者头像 李华
网站建设 2026/9/4 8:27:04

既要上班又要做家务:职场人的累,谁真的看见?

图1&#xff1a;既要上班又要做家务信息图——职场人的疲惫需要被看见白天在工位连轴转&#xff0c;晚上回家还有一屋子家务等着——“凭什么既要工作又要做家务”这个话题&#xff0c;今天冲上了热搜。据热榜&#xff0c;微博热搜“凭什么既要工作又要做家务”热度达到87.6万&…

作者头像 李华
网站建设 2026/9/4 8:25:42

C++综合实战:数据结构与算法实现及系列总结

本文是 C 系列教程的第 30 篇&#xff0c;也是系列终章。本篇实战数据结构与算法&#xff1a;手写动态数组与链表、排序与查找算法、递归与分治&#xff0c;最后回顾全部 30 篇学习路径&#xff0c;覆盖 9 个完整示例代码。一、手写动态数组 1.1 为什么手写容器 理解容器内部机…

作者头像 李华
网站建设 2026/9/4 8:25:13

2026年7月桂林市新房价格深度分析报告

一、报告背景与数据说明本报告基于2026年7月桂林市新房市场实际成交案例&#xff0c;结合各城区典型楼盘的真实成交数据&#xff0c;对当前桂林新房价格水平、区域分化特征及未来走势进行深度分析。数据来源涵盖桂林市住房和城乡建设局备案信息、主要房产交易平台公开成交记录及…

作者头像 李华