数据结构第13节 无向图

无向图是图论中的一个基本概念,它是数学和计算机科学中用来描述一组对象(顶点)以及它们之间的成对关系(边)的结构。在无向图中,边是没有方向的,这意味着边所连接的两个顶点可以互相访问。

定义

无向图 ( G ) 可以定义为一个有序对 ( G=(V,E) ),其中:

  • ( V ) 是顶点的集合,也称作节点的集合。
  • ( E ) 是边的集合,边是 ( V ) 中顶点的无序对,表示两个顶点之间的连接。

术语

  • 顶点:图中的基本单位,通常用字母 ( v ) 或 ( u ) 表示。
  • :连接顶点的线段,表示两个顶点之间的关系,通常用 ( e ) 表示。
  • 度数:一个顶点的度数是与该顶点相邻的所有边的数量。
  • 路径:一系列顶点和边,使得每个边都连接路径中的连续两个顶点。
  • 简单路径:路径中不重复经过任何顶点。
  • :闭合路径,起点和终点相同。
  • 连通性:如果图中任意两个顶点之间都存在路径,则称该图为连通图。
  • 连通分量:无向图中的最大连通子图,彼此之间没有边相连。

图的表示

无向图可以用以下几种方式表示:

  • 邻接矩阵:一个 ( |V| \times |V| ) 的矩阵,其中第 ( i ) 行第 ( j ) 列的元素为 1 如果顶点 ( i ) 和顶点 ( j ) 之间有一条边,否则为 0。
  • 邻接列表:对于每个顶点,维护一个链表,包含与之直接相连的所有顶点。

应用

无向图在许多领域有应用,如:

  • 社交网络:顶点可以代表人,边可以代表朋友关系。
  • 互联网:网页作为顶点,超链接作为边。
  • 电路设计:顶点可以是电路元件,边可以是连接导线。
  • 地图和道路网络:顶点可以是城市或交叉口,边可以是道路。
  • 化学分子结构:顶点可以是原子,边可以是化学键。

算法

处理无向图的一些常见算法包括:

  • 深度优先搜索 (DFS):从某个顶点开始,尽可能深入地探索每条路径。
  • 广度优先搜索 (BFS):从某个顶点开始,探索所有离起点等距离的顶点。
  • 最小生成树算法:如Prim算法或Kruskal算法,用于在加权图中找到一棵包含所有顶点的最小权重的树。
  • 连通性检测:确定图是否连通,或找出所有连通分量。

无向图是理解和解决许多复杂问题的基础工具。在实际应用中,无向图可以转化为有向图或加权图以适应更复杂的关系和需求。

在Java中,我们可以使用邻接矩阵或邻接列表来表示无向图。下面是一个使用邻接列表的例子:

import java.util.*;public class Graph {private final int V;   // Number of verticesprivate LinkedList<Integer> adj[]; //Adjacency List// ConstructorGraph(int v) {V = v;adj = new LinkedList[v];for (int i=0; i<v; ++i)adj[i] = new LinkedList();}//Function to add an edge into the graphvoid addEdge(int v,int w) {adj[v].add(w); // Add w to v’s list.adj[w].add(v); // Since graph is undirected, add v to w's list too}// Function to print the graphvoid printGraph() {for (int v = 0; v < V; ++v) {System.out.println("Adjacency list of vertex "+ v);System.out.print("head ");Iterator<Integer> it = adj[v].listIterator();while (it.hasNext())System.out.print(" -> " + it.next());System.out.println("\n");}}public static void main(String args[]) {Graph g = new Graph(5);g.addEdge(0, 1);g.addEdge(0, 4);g.addEdge(1, 2);g.addEdge(1, 3);g.addEdge(1, 4);g.addEdge(2, 3);g.addEdge(3, 4);g.printGraph();}
}

在这个例子中,我们首先定义了一个Graph类,它有两个私有变量:V(顶点的数量)和adj(邻接列表)。然后我们在构造函数中初始化这些变量。

我们定义了一个addEdge方法来添加边。由于这是一个无向图,所以我们需要在两个顶点的邻接列表中都添加对方。

最后,我们定义了一个printGraph方法来打印图的邻接列表表示。

在main方法中,我们创建了一个Graph对象,并添加了一些边,然后打印出了这个图。

当然,让我们再看一个使用邻接矩阵表示无向图的例子。邻接矩阵是一种二维数组,用于表示图中顶点之间的连接关系。如果图中的两个顶点u和v之间存在一条边,那么邻接矩阵中的元素A[u][v]和A[v][u]的值为1,否则为0。

下面是一个使用邻接矩阵表示无向图的Java代码示例:

public class Graph {private final int V;   // No. of verticesprivate int E;         // No. of edgesprivate int[][] adj;   // Adjacency Matrix// ConstructorGraph(int v) {V = v;E = 0;adj = new int[V][V];}// Method to add an edge in a graphpublic void addEdge(int v, int w) {if (v >= 0 && v < V && w >= 0 && w < V) {adj[v][w] = 1;adj[w][v] = 1;E++;} else {throw new IllegalArgumentException("Invalid vertices");}}// Method to print adjacency matrixpublic void printGraph() {for (int v = 0; v < V; v++) {for (int w = 0; w < V; w++) {System.out.print(adj[v][w] + " ");}System.out.println();}}public static void main(String[] args) {Graph g = new Graph(5);g.addEdge(0, 1);g.addEdge(0, 4);g.addEdge(1, 2);g.addEdge(1, 3);g.addEdge(1, 4);g.addEdge(2, 3);g.addEdge(3, 4);g.printGraph();}
}

在这个例子中,我们首先定义了一个Graph类,它有三个私有变量:V(顶点的数量),E(边的数量)和adj(邻接矩阵)。然后我们在构造函数中初始化这些变量。

我们定义了一个addEdge方法来添加边。由于这是一个无向图,所以我们需要在邻接矩阵的两个位置上都设置1。

最后,我们定义了一个printGraph方法来打印图的邻接矩阵表示。

在main方法中,我们创建了一个Graph对象,并添加了一些边,然后打印出了这个图的邻接矩阵表示。

让我们通过一个迷宫游戏的例子来理解无向图的应用。在这个游戏中,迷宫可以被看作是一个无向图,其中每个房间都是一个顶点,每个门(连接两个房间的通道)都是一条边。

假设我们有一个迷宫,它由多个房间组成,每个房间都有可能与其他房间相连。我们的目标是找到从起点到终点的路径。这个问题可以通过深度优先搜索(DFS)或广度优先搜索(BFS)在无向图中寻找路径来解决。

以下是一个使用DFS在迷宫(无向图)中寻找路径的Java代码示例:

import java.util.*;class Maze {private final int V;   // Number of roomsprivate LinkedList<Integer> adj[]; //Adjacency List// ConstructorMaze(int v) {V = v;adj = new LinkedList[v];for (int i=0; i<v; ++i)adj[i] = new LinkedList();}//Function to add a door between two roomsvoid addDoor(int v, int w) {adj[v].add(w); // Add w to v’s list.adj[w].add(v); // Since maze is undirected, add v to w's list too}// A recursive function to find path from source 's' to destination 'd'boolean DFSUtil(int s, int d, boolean visited[]) {visited[s] = true;System.out.print(s + " ");if (s == d)return true;Iterator<Integer> i = adj[s].listIterator();while (i.hasNext()) {int n = i.next();if (!visited[n]) {if (DFSUtil(n, d, visited))return true;}}return false;}// Prints shortest path from source 's' to destination 'd'void findPath(int s, int d) {boolean visited[] = new boolean[V];if (DFSUtil(s, d, visited) == false)System.out.println("No path exists");System.out.println();}public static void main(String args[]) {Maze maze = new Maze(9); // Assume we have 9 roomsmaze.addDoor(0, 1);maze.addDoor(0, 3);maze.addDoor(1, 2);maze.addDoor(1, 3);maze.addDoor(2, 4);maze.addDoor(3, 4);maze.addDoor(4, 5);maze.addDoor(5, 6);maze.addDoor(6, 7);maze.addDoor(7, 8);System.out.println("Path from room 0 to room 8:");maze.findPath(0, 8);}
}

在这个例子中,我们首先定义了一个Maze类,它有两个私有变量:V(房间的数量)和adj(邻接列表)。然后我们在构造函数中初始化这些变量。

我们定义了一个addDoor方法来添加门。由于这是一个无向图,所以我们需要在两个房间的邻接列表中都添加对方。

我们还定义了一个findPath方法来找到从源房间到目标房间的路径。这个方法使用了深度优先搜索(DFS)算法,并且使用了一个辅助方法DFSUtil来进行递归搜索。

在main方法中,我们创建了一个Maze对象,并添加了一些门,然后找到了从房间0到房间8的路径。

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

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

相关文章

vue项目实现堆叠卡片拖动切换效果

实际效果 实现流程 1. 实现卡片位置堆叠 将父元素的 position 设置成relative &#xff0c;卡片的position 设置成 absolute 即可。 2. 消除图片的移动 如果卡片上有图片&#xff0c;默认拖动的时候就会导致像上图一样变成了选中图片移动&#xff0c;从而没法触发拖动事件。消…

苹果电脑能玩赛博朋克2077吗 如何在mac上运行赛博朋克2077 crossover能玩什么游戏

各位喜欢赛博朋克风的一定不能错过《赛博朋克2077》。那么《赛博朋克2077》是一款什么样的游戏&#xff1f;《赛博朋克2077》在苹果电脑上可以运行吗&#xff1f;一起来看看介绍吧。 一、《赛博朋克2077》是一款什么样的游戏&#xff1f; 《赛博朋克2077》是一款由CD Projekt …

MIT6.s081 2021 Lab Traps

使用gdb调试xv6内核 从最近两个 Lab 开始&#xff0c;代码逻辑的复杂度明显上升&#xff0c;对内核进行调试可能是帮助理解操作系统机制的绝佳方法。因此在开始本 Lab 之前&#xff0c;我们先来配置一下针对 xv6 内核的 gdb 调试器。 安装 gdb-multiarch. 利用包管理工具进行…

基于Maximin的异常检测方法(MATLAB)

异常存在于各个应用领域之中&#xff0c;往往比正常所携带的信息更多也更为重要。例如医疗系统中疾病模式&#xff0c;信用卡消费中的欺诈行为&#xff0c;数据库中数据泄露&#xff0c;大型机器故障&#xff0c;网络入侵行为等。大数据技术体系的快速兴起与发展&#xff0c;加…

【React Native优质开源项目】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

字符串——string类的常用接口

一、string类对象的常见构造 二、string类对象的容量操作 三、string类对象的访问及遍历操作 四、string类对象的修改操作 一、string类对象的常见构造 1.string() ——构造空的string类对象&#xff0c;也就是空字符串 2.string(const char* s) ——用字符串来初始化stri…

如何成为一个优秀的软件产品开发经理

成为一名优秀的软件产品开发经理&#xff0c;需要综合技术、管理、市场和人际交往等多方面的能力。以下是成为优秀软件产品开发经理的关键步骤和技能&#xff1a; 1. 技术背景与理解 技术知识&#xff1a;虽然不需要成为某一领域的顶级专家&#xff0c;但对软件开发流程、常用…

【Linux】压缩命令——gzip,bzip2,xz

1.压缩文件的用途与技术 你是否有过文件太大&#xff0c;导致无法以正常的E-mail方式发送&#xff1f;又或学校、厂商要求使用CD或DVD来做数据归档之用&#xff0c;但是你的单一文件却都比这些传统的一次性存储媒介还要大&#xff0c;那怎么分成多块来刻录&#xff1f;还有&am…

【QT】显示类控件

显示类控件 显示类控件1. label - 标签2. LCD Number - 显示数字的控件3. ProgressBar - 进度条4. Calendar Widget - 日历5. Line Edit - 输入框6. Text Edit - 多行输入框7. Combo Box - 下拉框8. Spin Box - 微调框9. Date Edit & Time Edit - 日期微调框10. Dial - 旋钮…

Windows 11中的WSL(Windows Subsystem for Linux)详细介绍与安装过程

文章目录 Windows 11中的WSL&#xff08;Windows Subsystem for Linux&#xff09;详细介绍与安装过程一、WSL简介二、WSL安装过程三、WSL常见应用场景四、常见问题和解决方案五、结论 Windows 11中的WSL&#xff08;Windows Subsystem for Linux&#xff09;详细介绍与安装过程…

Hive 高可用分布式部署详细步骤

目录 系统版本说明 hive安装包下载及解压 上传mysql-connector-java的jar包 配置环境变量 进入conf配置文件中&#xff0c;将文件重命名 在hadoop集群上创建文件夹 创建本地目录 修改hive-site.xml文件 同步到其他的节点服务器 修改node02中的配置 hive-site.xml 修改…

昇思25天学习打卡营第3天|MindSpore张量

# 打卡 目录 # 打卡 类 涉及知识点 1. 创建张量的4种方式 运行例子 2. 张量属性和索引 运行例子 3. 张量运算 运行例子 4. Tensor 与 Numpy 转换 5. 稀疏张量&#xff1a;CSR和COO CSRTensor 运行例子 COOTensor 运行例子 RowTensor 类 import mindspore from…

Linux系统的介绍和常用命令

文章目录 介绍常用命令文件和目录操作文件内容操作系统管理命令网络命令 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;Liunx系统 ✨文章内容&#xff1a;Liunx系统介绍 &…

2024年【危险化学品生产单位安全生产管理人员】考试总结及危险化学品生产单位安全生产管理人员考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品生产单位安全生产管理人员考试总结是安全生产模拟考试一点通总题库中生成的一套危险化学品生产单位安全生产管理人员考试试题&#xff0c;安全生产模拟考试一点通上危险化学品生产单位安全生产管理人员作业…

【MySQL】3.表的操作

表的操作 一.创建表二.查看表三.修改表四.删除表 一.创建表 create table [if not exists] tb_name( field1 datatype comment 说明, field2 datatype, field3 datatype) charsetutf8 collateutf8_gerenal_ci engineInnoDB//表的编码集&#xff0c;校验集如果不指定&#xff…

【xinference】(15):在compshare上,使用docker-compose运行xinference和chatgpt-web项目,配置成功!!!

视频演示 【xinference】&#xff08;15&#xff09;&#xff1a;在compshare上&#xff0c;使用docker-compose运行xinference和chatgpt-web项目&#xff0c;配置成功&#xff01;&#xff01;&#xff01; 1&#xff0c;安装docker方法&#xff1a; #!/bin/shdistribution$(…

Linux上将图片转换为PDF

在Linux系统中&#xff0c;将图片转换为PDF文件的常见方法是使用ImageMagick这个工具。 1、下载ImageMagick&#xff1a; 首先需要安装ImageMagick&#xff0c;可以通过包管理器安装&#xff0c;例如在Ubuntu上使用&#xff1a; sudo apt update sudo apt install imagemagic…

路径跟踪算法之PID、PP、Stanley详细理解

一、前言 今天又来补作业了&#xff01; 在跟踪控制领域&#xff0c;PID&#xff08;Proportional-Integral-Derivative, 分别为比例、积分、微分&#xff09;、PP&#xff08; Pure-Puresuit, 纯跟踪&#xff09;、Stanley&#xff08;前轮反馈控制&#xff09;是三种最为常见…

Rust 组织管理

Rust 组织管理 Rust 是一种系统编程语言&#xff0c;以其内存安全性、速度和并发性而闻名。它由 Mozilla 开发&#xff0c;并得到了一个庞大而活跃的社区的支持。Rust 的组织管理涉及多个方面&#xff0c;包括项目管理、社区参与、工具和库的维护&#xff0c;以及生态系统的整…

STL——map和set

目录 一、set 二、map 1.插入 2.隆重介绍 [] A使用场景 B原理 一、set set即STL库中提供的K模型的二叉搜索树&#xff0c;他的函数使用和其他容器很相似&#xff0c;可以自行阅读文档#include <set> 本文旨对库中难以理解的函数作说明 二、map map即KV模型的二…