数据结构与算法:图形数据结构

1. 图的基本概念和表示方法

图是一种由节点和边组成的非线性数据结构,用于描述事物之间的关系。在计算机科学中,图是一种十分重要的数据结构,广泛应用于各种领域,如网络分析、路径规划等。本节将介绍图的基本概念和两种常见的表示方法:邻接矩阵和邻接表。

1.1 图的定义

在图论中,图(Graph)是由顶点集合和边集合组成的一种数学模型。图可以表示任意的关系,例如社交网络中的用户和好友之间的关系,地图上的城市和道路之间的连接关系等。

图可以分为有向图和无向图两种类型。在有向图中,边是有方向的,表示从一个顶点到另一个顶点的箭头。而在无向图中,边是无方向的,表示两个顶点之间的双向关系。

1.2 图的表示方法

邻接矩阵

邻接矩阵是使用二维数组表示图的连接关系的一种方式。矩阵的行和列分别对应图中的顶点,矩阵中的元素表示顶点之间是否存在边。如果图是无向图,则矩阵是对称的;如果是有向图,则不一定对称。

让我们通过一个示例来说明邻接矩阵的表示方法:

// 一个简单的无向图的邻接矩阵表示
int[][] adjacencyMatrix = {{0, 1, 1, 0, 0},  // 顶点 0 与顶点 1、2 相连{1, 0, 0, 1, 0},  // 顶点 1 与顶点 0、3 相连{1, 0, 0, 1, 1},  // 顶点 2 与顶点 0、3、4 相连{0, 1, 1, 0, 0},  // 顶点 3 与顶点 1、2 相连{0, 0, 1, 0, 0}   // 顶点 4 与顶点 2 相连
};

在上面的示例中,数组中的值表示相应顶点之间是否有边相连。值为 1 表示相连,值为 0 表示不相连。

邻接表

邻接表是使用链表或数组的方式表示图的连接关系的一种方式。对于每个顶点,我们可以使用一个列表来存储与其相邻的顶点。这种表示方法适用于稀疏图,因为它节省了空间。

让我们通过一个示例来说明邻接表的表示方法:

import java.util.*;// 图的邻接表表示
class Graph {int V; // 顶点数LinkedList<Integer>[] adjacencyList; // 邻接表// 构造函数Graph(int v) {V = v;adjacencyList = new LinkedList[v];for (int i = 0; i < v; ++i) {adjacencyList[i] = new LinkedList();}}// 添加边void addEdge(int v, int w) {adjacencyList[v].add(w);adjacencyList[w].add(v); // 如果是有向图,则去掉此行}
}

在上面的示例中,我们使用了一个数组来存储邻接表,数组中的每个元素是一个链表,存储与该顶点相邻的顶点。通过添加边的操作,我们可以构建出图的邻接表表示。

2. 图的遍历算法

图的遍历算法是图算法中的基础部分,用于访问图中的所有节点。常用的图遍历算法包括深度优先搜索(DFS)和广度优先搜索(BFS)。本节将详细介绍这两种算法的原理、实现方式以及在图中的应用场景。

2.1 深度优先搜索(DFS)

深度优先搜索是一种用于遍历或搜索图或树的算法。它从起始顶点开始,沿着一条路径尽可能深地搜索,直到到达最深处,然后回溯并继续搜索其他路径。DFS可以使用递归或栈来实现。

让我们通过一个示例来说明DFS算法的基本原理和实现方式:

import java.util.*;// 图的深度优先搜索
class Graph {private int V; // 顶点数private LinkedList<Integer>[] adjacencyList; // 邻接表// 构造函数Graph(int v) {V = v;adjacencyList = new LinkedList[v];for (int i = 0; i < v; ++i) {adjacencyList[i] = new LinkedList();}}// 添加边void addEdge(int v, int w) {adjacencyList[v].add(w);}// 深度优先搜索算法void DFSUtil(int v, boolean[] visited) {visited[v] = true;System.out.print(v + " ");Iterator<Integer> iterator = adjacencyList[v].listIterator();while (iterator.hasNext()) {int n = iterator.next();if (!visited[n]) {DFSUtil(n, visited);}}}// 对外接口,用于调用深度优先搜索算法void DFS(int v) {boolean[] visited = new boolean[V];DFSUtil(v, visited);}
}// 示例代码
public class Main {public static void main(String[] args) {Graph graph = new Graph(4);graph.addEdge(0, 1);graph.addEdge(0, 2);graph.addEdge(1, 2);graph.addEdge(2, 0);graph.addEdge(2, 3);graph.addEdge(3, 3);System.out.println("深度优先遍历结果:");graph.DFS(2);}
}

在上面的示例中,我们定义了一个Graph类来表示图,并实现了深度优先搜索算法。通过调用DFS方法,我们可以从指定的起始顶点开始进行深度优先搜索,并输出遍历结果。

2.2 广度优先搜索(BFS)

广度优先搜索是一种用于遍历或搜索图或树的算法。它从起始顶点开始,逐层遍历图的所有节点,直到找到目标节点或遍历完整个图。BFS可以使用队列来实现。

让我们通过一个示例来说明BFS算法的基本原理和实现方式:

import java.util.*;// 图的广度优先搜索
class Graph {private int V; // 顶点数private LinkedList<Integer>[] adjacencyList; // 邻接表// 构造函数Graph(int v) {V = v;adjacencyList = new LinkedList[v];for (int i = 0; i < v; ++i) {adjacencyList[i] = new LinkedList();}}// 添加边void addEdge(int v, int w) {adjacencyList[v].add(w);}// 广度优先搜索算法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 + " ");Iterator<Integer> iterator = adjacencyList[s].listIterator();while (iterator.hasNext()) {int n = iterator.next();if (!visited[n]) {visited[n] = true;queue.add(n);}}}}
}// 示例代码
public class Main {public static void main(String[] args) {Graph graph = new Graph(4);graph.addEdge(0, 1);graph.addEdge(0, 2);graph.addEdge(1, 2);graph.addEdge(2, 0);graph.addEdge(2, 3);graph.addEdge(3, 3);System.out.println("广度优先遍历结果:");graph.BFS(2);}
}

在上面的示例中,我们同样定义了一个Graph类来表示图,并实现了广度优先搜索算法。通过调用BFS方法,我们可以从指定的起始顶点开始进行广度优先搜索,并输出遍历结果。

3. 图的应用场景和算法

图作为一种非线性数据结构,在现实生活和计算机科学中有着广泛的应用。本节将介绍图在实际场景中的应用,并探讨一些常见的图算法。

3.1 最短路径算法

最短路径算法用于寻找图中两个顶点之间的最短路径,其在网络路由、地图导航等领域有着重要的应用。常见的最短路径算法包括Dijkstra算法和Bellman-Ford算法。

  • Dijkstra算法:该算法用于计算从起始顶点到图中所有其他顶点的最短路径。它采用贪心策略,每次选择当前最短路径的顶点进行扩展,直到找到目标顶点或者遍历完整个图。Dijkstra算法适用于没有负权边的图。

  • Bellman-Ford算法:与Dijkstra算法不同,Bellman-Ford算法可以处理图中存在负权边的情况。该算法采用动态规划的思想,通过多次迭代来不断更新顶点的最短路径估计值,直到收敛为止。

3.2 最小生成树算法

最小生成树算法用于寻找连接图中所有顶点的最小连通子图,其在网络设计、电路布线等领域有着重要的应用。常见的最小生成树算法包括Prim算法和Kruskal算法。

  • Prim算法:该算法从一个初始顶点开始,逐步添加边,直到所有顶点都被包含在生成树中。Prim算法使用贪心策略,每次选择当前与生成树相邻且权值最小的边进行扩展。

  • Kruskal算法:与Prim算法不同,Kruskal算法是一种基于边的贪心算法。该算法先将所有边按权值从小到大排序,然后依次选择权值最小的边,如果该边的两个端点不在同一个连通分量中,则将其加入最小生成树。

4. 图形数据结构的应用案例

图形数据结构在现实生活和计算机科学中有着广泛的应用,本节将介绍几个图形数据结构在不同领域的应用案例。

4.1 社交网络分析

社交网络是一个复杂的图形结构,其中的个体可以被表示为图的顶点,而他们之间的关系可以被表示为图的边。社交网络分析通过对这些关系进行挖掘和分析,可以揭示出用户之间的关联性、影响力以及信息传播的规律。

举例来说,我们可以利用图的遍历算法,如深度优先搜索(DFS)或广度优先搜索(BFS),来寻找特定用户的朋友圈或关联群体。此外,最短路径算法也可以用于寻找两个用户之间的最短关系链。

4.2 路网规划

在城市交通规划和导航系统中,道路和交通节点可以被建模为图的顶点和边。利用图的最短路径算法,可以高效地规划出从起点到终点的最优路线,从而提高交通效率,减少交通拥堵。

例如,导航软件通过实时监测道路交通状况,并结合最短路径算法,为驾驶员提供实时的最佳导航路线,减少行车时间和油耗。

4.3 电路布线

在电子工程领域,电路布线是一个关键的设计问题。电路中的元件和连接可以被视为图的顶点和边。最小生成树算法可以用于设计电路布线,以减少电路的成本和功耗,提高电路的稳定性和可靠性。

通过将电路布线问题抽象为图的最小生成树问题,可以有效地优化电路设计,达到节约成本、提高性能的目的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/701757.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++知识点总结(22):模拟算法

一、概念 模拟算法 根据题目描述进行筛选提取关键要素&#xff0c;按需求书写代码解决实际问题的算法。 二、步骤 1、提取题目的关键要素 2、根据关键要素的需求完成代码 三、关键要素 1、题目目的 2、样例的执行逻辑&#xff08;样例分析&#xff09; 3、数据范围&#xff08;…

上门服务系统|上门服务小程序|上门服务软件开发

随着移动互联网技术的普及&#xff0c;上门服务小程序系统成为现代企业数字化转型的关键一环。这一系统为消费者提供了更加便捷、高效以及个性化的服务体验&#xff0c;同时也为企业带来了更广阔的商业机会。让我们来看看上门服务小程序系统的优势和功能。 首先&#xff0c;上门…

vue3新特性-defineOptions和defineModel

defineOptions 背景说明&#xff1a; 有 <script setup> 之前&#xff0c;如果要定义 props, emits 可以轻而易举地添加一个与 setup 平级的属性。 但是用了 <script setup> 后&#xff0c;就没法这么干了 setup 属性已经没有了&#xff0c;自然无法添加与其平…

Docker基础篇(二)

docker run -d docker run -d 容器名或容器ID docker run -d 后台生成容器&#xff0c;并退出容器&#xff08;除容器中在运行脚本&#xff09; docker run -it 交互生成容器 docker run -d centos /bin/sh -c “while true; do echo zen; sleep 2;done” 查看容器中的进程…

【进程创建】

目录 进程创建的方式查看进程pid 调用系统调用创建子进程fock函数做了的工作子进程刚开始创建的状态 一个变量&#xff0c;两个不同的值创建子进程的作用 进程创建的方式 1.在操作系统上输入的指令。 2.已经启动的软件。 3.程序员在代码层面上调用系统调用创建进程。 linux中第…

服务器被黑该如何查找入侵痕迹以及如何防御攻击

当公司的网站服务器被黑&#xff0c;被入侵导致整个网站&#xff0c;以及业务系统瘫痪&#xff0c;给企业带来的损失无法估量&#xff0c;但是当发生服务器被攻击的情况&#xff0c;作为服务器的维护人员应当在第一时间做好安全响应&#xff0c;对服务器以及网站应以最快的时间…

【Java程序设计】【C00287】基于Springboot的疫情防控期间某村外出务工人员管理系统(有论文)

基于Springboot的疫情防控期间某村外出务工人员管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的疫情防控期间某村外出务工人员信息管理系统 本系统分为系统功能模块、管理员功能模块、用户功能模块、采集…

git 获取仓库代码与提交代码

1. 建文件夹&#xff0c;获取项目的完整代码 2.Git安装 打开安装程序后&#xff0c;一直点击下一步&#xff0c;直到以下位置&#xff1a; 此处代表使用VIM作为Git默认的编辑器。继续下一步&#xff0c;直到: 这里选择第一项&#xff0c;即仅仅在Bash中使用Git。如果有Linux的学…

面了 360、腾讯和百度的 NLP 算法岗,被问麻了。。。。。

文章目录 技术交流群1、360 NLP 算法岗2、腾讯 NLP 算法岗3、百度 NLP 算法岗用通俗易懂方式讲解系列 节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂同学、参加社招和校招面试的同学&#xff0c;针对大模型技术趋势、大模型落地项…

后台管理登录权限怎么实现的,token具体有什么作用

后台管理系统的登录权限通常是通过以下步骤实现的&#xff1a; 用户输入用户名和密码进行登录。 后端接收到登录请求后&#xff0c;验证用户名和密码的正确性。 如果用户名和密码正确&#xff0c;后端会生成一个令牌&#xff08;Token&#xff09;&#xff0c;并将该令牌返回给…

281.【华为OD机试真题】贪吃的猴子(滑动窗口和动态规划—JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-贪吃的猴子二.解题思路三.题解代码Python题解代…

ASCII编码的影响与作用:数字化时代的不可或缺之物

title: ASCII编码的影响与作用&#xff1a;数字化时代的不可或缺之物 date: 2024/2/25 16:03:37 updated: 2024/2/25 16:03:37 tags: ASCII起源标准化字符文本处理基础编程语言基石数据库存储标准跨平台兼容多语言编码基础 一、ASCII编码的起源 ASCII&#xff08;American St…

Qt的QFileSystemModel与QTreeView、QTableView、QListView的组合使用

1.相关描述 QFileSystemModel与QTreeView、QTableView、QListView的组合&#xff0c;当QTreeView点击发生改变&#xff0c;QTableView和QListView也会发生变化 2.相关界面 3.相关代码 mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h"…

2.WEB渗透测试-前置基础知识-web基础知识和操作系统

web基础知识 1.http协议 超文本传输协议是互联网上应用最广泛的一种网络协议。所有www文件都必须遵守的一个标准&#xff0c;是以 ASCII 码传输&#xff0c;建立在 TCP/IP 协议之上的应用层规范&#xff0c;通俗点说就是一种固定的通讯规则。 2、网络的三种架构及特点 网络应…

备战蓝桥杯————双指针技巧巧解数组3

利用双指针技巧来解决七道与数组相关的题目。 两数之和 II - 输入有序数组&#xff1a; 给定一个按升序排列的数组&#xff0c;找到两个数使它们的和等于目标值。可以使用双指针技巧&#xff0c;在数组两端设置左右指针&#xff0c;根据两数之和与目标值的大小关系移动指针。 …

年关将至送大礼 社区适时献爱心

在这个快节奏的时代&#xff0c;社区作为人们生活的重要组成部分&#xff0c;其凝聚力和互助精神显得尤为重要。2024年2月7日&#xff0c;实践队员李若钰有幸参与了社区礼盒分装的活动&#xff0c;这不仅仅是一次简单的劳动&#xff0c;更是一次心灵的洗礼和感悟。 礼盒分装&am…

Ansible user 模块 该模块主要是用来管理用户账号

目录 参数语法验证创建用户删除用户验证 删除用户 参数 comment  # 用户的描述信息 createhome  # 是否创建家目录 force  # 在使用stateabsent时, 行为与userdel –force一致. group  # 指定基本组 groups  # 指定附加组&#xff0c;如果指定为(groups)表示删除所有…

【深度学习目标检测】十九、基于深度学习的芒果计数分割系统-含数据集、GUI和源码(python,yolov8)

使用深度学习算法检测芒果具有显著的优势和应用价值。以下是几个主要原因&#xff1a; 特征学习的能力&#xff1a;深度学习&#xff0c;特别是卷积神经网络&#xff08;CNN&#xff09;&#xff0c;能够从大量的芒果图像中自动学习和提取特征。这些特征可能是传统方法难以手动…

JAVA算法和数据结构

一、Arrays类 1.1 Arrays基本使用 我们先认识一下Arrays是干什么用的&#xff0c;Arrays是操作数组的工具类&#xff0c;它可以很方便的对数组中的元素进行遍历、拷贝、排序等操作。 下面我们用代码来演示一下&#xff1a;遍历、拷贝、排序等操作。需要用到的方法如下 public…

gensim 实现 TF-IDF

目录 介绍 代码 介绍 TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09; 含义&#xff1a; TF (Term Frequency): 词频&#xff0c;是指一个词语在当前文档中出现的次数。它衡量的是词语在文档内部的重要性&#xff0c;直观上讲&#xff0c;一个词…