数据结构入门-13-图

文章目录

  • 一、图的概述
    • 1.1 图论的作用
    • 1.2 图的分类
      • 1.2.1 无向图
      • 1.2.2 有向图
      • 1.2.3 无权图
      • 1.2.4 有劝图
    • 1.3 图的基本概念
  • 二、树的基本表示
    • 2.1 邻接矩阵
      • 2.1.1 邻接矩阵 表示图
      • 2.1.2 邻接矩阵的复杂度
    • 2.2 邻接表
      • 2.2.1 邻接表的复杂度
      • 2.2.2 邻接表By哈希表
  • 三、图的深度优先遍历
    • 3.1 图深度遍历过程
    • 3.2 图遍历改进
    • 3.3 先中后
    • 3.4 复杂度
  • 四、深度遍历的应用
    • 4.1 求联通分量
    • 4.2 单源路径问题
    • 4.3 检测无向图中的环
    • 4.4 二分图检测
  • 五、图的广度优先遍历
  • 六、图论问题的建模
  • 七、图论和AI
  • 十一、最小生成树
    • 11.1 带权图
  • 十二、最短路径
    • 12.1 迪杰斯特拉算法
      • 12.1.1 Dijkstra原理

一、图的概述

1.1 图论的作用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.2 图的分类

在这里插入图片描述

1.2.1 无向图

在这里插入图片描述

1.2.2 有向图

在这里插入图片描述在这里插入图片描述

1.2.3 无权图

在这里插入图片描述

1.2.4 有劝图

在这里插入图片描述

1.3 图的基本概念

  1. 两点相邻
  2. 点的邻边
  3. 路径Path,从一个点到另一个点走过的路
  4. 环Loop,多个点围城一个圈
  5. 自环边,自己和自己形成环
  6. 平行边,重复的边

在这里插入图片描述

  1. 联通分量
    在这里插入图片描述

  2. 无环图
    在这里插入图片描述
    树是一种无环图,一个联通的无环图(一个联通分量)就是树

  3. 连通图的 生成树
    在这里插入图片描述
    V:顶点数

在这里插入图片描述
10) 顶点的度degree
顶点相邻的边数
在这里插入图片描述

二、树的基本表示

2.1 邻接矩阵

在这里插入图片描述
在这里插入图片描述

V:顶点数,E:边数

2.1.1 邻接矩阵 表示图

import java.io.*;
import java.util.Scanner;public class AdjMatrix {private int V;private int E;private int[][] adj;public AdjMatrix(String filename){File file = new File(filename);try(Scanner scanner = new Scanner(file)){V = scanner.nextInt();adj = new int[V][V];E = scanner.nextInt();for(int i = 0; i < E; i ++){int a = scanner.nextInt();int b = scanner.nextInt();adj[a][b] = 1;adj[b][a] = 1;}}catch(IOException e){e.printStackTrace();}}@Overridepublic String toString(){StringBuilder sb = new StringBuilder();sb.append(String.format("V = %d, E = %d\n", V, E));for(int i = 0; i < V; i ++){for(int j = 0; j < V; j ++)sb.append(String.format("%d ", adj[i][j]));sb.append('\n');}return sb.toString();}public static void main(String[] args){AdjMatrix adjMatrix = new AdjMatrix("src/main/java/hGraph/base/file/g.txt");System.out.print(adjMatrix);}
}
    public int V(){return V;}public int E(){return E;}//判断是否有边,两顶点是否相邻public boolean hasEdge(int v, int w){validateVertex(v);validateVertex(w);return adj[v][w] == 1;}
//查找和顶点v相连的顶点public ArrayList<Integer> adj(int v){validateVertex(v);ArrayList<Integer> res = new ArrayList<>();for(int i = 0; i < V; i ++)if(adj[v][i] == 1)res.add(i);return res;}
//查找顶点的度public int degree(int v){return adj(v).size();}

2.1.2 邻接矩阵的复杂度

在这里插入图片描述

空间复杂度 可以优化,
求一个点的相邻结点 可以优化

稀疏图&稠密图
根据边的多少

完全图 每个顶点都连接

在这里插入图片描述

2.2 邻接表

在这里插入图片描述

2.2.1 邻接表的复杂度

在这里插入图片描述
在这里插入图片描述

2.2.2 邻接表By哈希表

在这里插入图片描述
用红黑树实现图

import java.io.File;
import java.io.IOException;
import java.util.TreeSet;
import java.util.Scanner;public class AdjSet {private int V;private int E;private TreeSet<Integer>[] adj;public AdjSet(String pathStr){File file = new File(pathStr);try(Scanner scanner = new Scanner(file)){V = scanner.nextInt();if(V < 0) throw new IllegalArgumentException("V must be non-negative");adj = new TreeSet[V];for(int i = 0; i < V; i ++)adj[i] = new TreeSet<Integer>();E = scanner.nextInt();if(E < 0) throw new IllegalArgumentException("E must be non-negative");for(int i = 0; i < E; i ++){int a = scanner.nextInt();validateVertex(a);int b = scanner.nextInt();validateVertex(b);if(a == b) throw new IllegalArgumentException("Self Loop is Detected!");if(adj[a].contains(b)) throw new IllegalArgumentException("Parallel Edges are Detected!");adj[a].add(b);adj[b].add(a);}}catch(IOException e){e.printStackTrace();}}private void validateVertex(int v){if(v < 0 || v >= V)throw new IllegalArgumentException("vertex " + v + "is invalid");}public int V(){return V;}public int E(){return E;}public boolean hasEdge(int v, int w){validateVertex(v);validateVertex(w);return adj[v].contains(w);}public Iterable<Integer> adj(int v){// public TreeSet<Integer> adj(int v){validateVertex(v);return adj[v];}public int degree(int v){validateVertex(v);return adj[v].size();}@Overridepublic String toString(){StringBuilder sb = new StringBuilder();sb.append(String.format("V = %d, E = %d\n", V, E));for(int v = 0; v < V; v ++){sb.append(String.format("%d : ", v));for(int w : adj[v])sb.append(String.format("%d ", w));sb.append('\n');}return sb.toString();}public static void main(String[] args){AdjSet adjSet = new AdjSet("g.txt");System.out.print(adjSet);}
}

三、图的深度优先遍历

3.1 图深度遍历过程

之前描述过树的遍历
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    public GraphDFS(Graph G){this.G = G;visited = new boolean[G.V()];dfs(0);}private void dfs(int v){visited[v] = true;order.add(v);for(int w: G.adj(v))if(!visited[w])dfs(w);}

3.2 图遍历改进

在这里插入图片描述

不和0 相连 的顶点,就不会遍历
原因是只针对0 调用
改进:对每一个节点进行调用
在这里插入图片描述

    public GraphDFS(Graph G){this.G = G;visited = new boolean[G.V()];for(int v = 0; v < G.V(); v ++)if(!visited[v])dfs(v);}private void dfs(int v){visited[v] = true;pre.add(v);for(int w: G.adj(v))if(!visited[w])dfs(w);post.add(v);}public Iterable<Integer> pre(){return pre;}public Iterable<Integer> post(){return post;}

3.3 先中后

在树中有先中后遍历
在这里插入图片描述

图也可以分为 先 后序遍历

在这里插入图片描述

3.4 复杂度

遍历的复杂度:O(V+E)

四、深度遍历的应用

4.1 求联通分量

在这里插入图片描述

4.2 单源路径问题

在这里插入图片描述
依然做了深度优先遍历,记录这个顶点的pre:从哪里来的
单源路径:从一个顶点出发的路径,不能反向查找

import java.util.ArrayList;
import java.util.Collections;public class SingleSourcePath {private Graph G;private int s;private boolean[] visited;private int[] pre;public SingleSourcePath(Graph G, int s){G.validateVertex(s);this.G = G;this.s = s;visited = new boolean[G.V()];pre = new int[G.V()];dfs(s, s);}private void dfs(int v, int parent){visited[v] = true;pre[v] = parent;for(int w: G.adj(v))if(!visited[w])dfs(w, v);}public boolean isConnectedTo(int t){G.validateVertex(t);return visited[t];}public Iterable<Integer> path(int t){ArrayList<Integer> res = new ArrayList<Integer>();if(!isConnectedTo(t)) return res;int cur = t;while(cur != s){res.add(cur);cur = pre[cur];}res.add(s);Collections.reverse(res);return res;}public static void main(String[] args){Graph g = new Graph("g.txt");SingleSourcePath sspath = new SingleSourcePath(g, 0);System.out.println("0 -> 6 : " + sspath.path(6));System.out.println("0 -> 5 : " + sspath.path(5));}
}

在这里插入图片描述

4.3 检测无向图中的环

在这里插入图片描述

4.4 二分图检测

二分图:
在这里插入图片描述

五、图的广度优先遍历

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

    public GraphBFS(Graph G){this.G = G;visited = new boolean[G.V()];for(int v = 0; v < G.V(); v ++)if(!visited[v])bfs(v);}private void bfs(int s){Queue<Integer> queue = new LinkedList<>();queue.add(s);visited[s] = true;while(!queue.isEmpty()){int v = queue.remove();order.add(v);for(int w: G.adj(v))if(!visited[w]){queue.add(w);visited[w] = true;}}}public Iterable<Integer> order(){return order;}

复杂度:O(V+E)

六、图论问题的建模

七、图论和AI

十一、最小生成树

11.1 带权图

在这里插入图片描述

/// 暂时只支持无向带权图
public class WeightedGraph implements Cloneable{private int V;private int E;private TreeMap<Integer, Integer>[] adj;public WeightedGraph(String filename){File file = new File(filename);try(Scanner scanner = new Scanner(file)){V = scanner.nextInt();if(V < 0) throw new IllegalArgumentException("V must be non-negative");adj = new TreeMap[V];for(int i = 0; i < V; i ++)adj[i] = new TreeMap<Integer, Integer>();E = scanner.nextInt();if(E < 0) throw new IllegalArgumentException("E must be non-negative");for(int i = 0; i < E; i ++){int a = scanner.nextInt();validateVertex(a);int b = scanner.nextInt();validateVertex(b);int weight = scanner.nextInt();if(a == b) throw new IllegalArgumentException("Self Loop is Detected!");if(adj[a].containsKey(b)) throw new IllegalArgumentException("Parallel Edges are Detected!");adj[a].put(b, weight);adj[b].put(a, weight);}}catch(IOException e){e.printStackTrace();}}

十二、最短路径

带权图的最短路径不一定 走的边最少
在这里插入图片描述

12.1 迪杰斯特拉算法

12.1.1 Dijkstra原理

  1. 指定dis:源到各个顶点的路径,先初始为MAX
    在这里插入图片描述

  2. 找顶点,更新dis
    在这里插入图片描述

  3. 找当前最短的路径,确定这个就是到顶点的最短路径:确定2位0到2的最短路径
    在这里插入图片描述

  4. 根据2顶点,来做更新
    在这里插入图片描述
    这里更新了2 到各个顶点的路径,1 从 4 更新到了3

  5. 再从当前的路径中找最小的,为3 顶点1,
    所以确定顶点1 的最短路径为3

在这里插入图片描述

  1. 再根据顶点1 ,更新dis
    在这里插入图片描述
  2. 确定当前最短的距离为5 ,顶点3
    在这里插入图片描述
  3. 更新dis,到顶点4都为6

在这里插入图片描述

每轮循环:

  1. 初始化源到其他顶点的dis,默认都为MAX
  2. 找到当前没有访问的最短路节点
  3. 确定这个节点的最短路径就是当前大小
  4. 根据这个节点的最短路径大小,更新到其他节点的路径长度,如果比dis中的要小,那么就更新dis

在这里插入图片描述

#from ChatGPT
1.初始化距离数组dist和标记数组visited。将起始地点设置为起点,其他地点的距离初始化为无穷大,visited数组初始化为false。
2.从起点开始遍历所有地点,选择当前距离最小且未被访问过的地点u。
3.对于地点u,更新与其相邻的地点v的距离,如果新的距离小于原来的距离,则更新距离数组dist和路径数组path。
4.标记地点u为已访问,重复上述过程,直到所有地点都被访问。
5.最终得到起点到每个地点的最短距离和路径。

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

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

相关文章

sentinel加密狗使用及规则配置

Sentinel加密狗是一种硬件加密设备&#xff0c;用于保护软件应用程序免受未经授权的访问和复制。它可以提供软件许可管理、访问控制和数据保护等功能。下面是Sentinel加密狗的使用及规则配置的相关介绍。 Sentinel加密狗的使用 插入加密狗&#xff1a;将Sentinel加密狗插入计算…

C51智能小车(循迹、跟随、避障、测速、蓝牙、wifie、4g、语音识别)总结

目录 1.电机模块开发 1.1 让小车动起来 1.2 串口控制小车方向 1.3 如何进行小车PWM调速 1.4 PWM方式实现小车转向 2.循迹小车 2.1 循迹模块使用 2.2 循迹小车原理 2.3 循迹小车核心代码 3.跟随/避障小车 3.1 红外壁障模块分析​编辑 3.2 跟随小车的原理 3.3 跟随小…

Leetcode.174 地下城游戏

题目链接 Leetcode.174 地下城游戏 hard 题目描述 恶魔们抓住了公主并将她关在了地下城 d u n g e o n dungeon dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公…

【高阶产品策略】设计有效的AB测试

文章目录 1、A/B测试概述2、A/B测试实施过程3、A/B测试中需要注意的地方4、从一个案例中看A/B测试 1、A/B测试概述 2、A/B测试实施过程 3、A/B测试中需要注意的地方 4、从一个案例中看A/B测试

编写中间件以用于 Express 应用程序

概述 中间件函数能够访问请求对象 (req)、响应对象 (res) 以及应用程序的请求/响应循环中的下一个中间件函数。下一个中间件函数通常由名为 next 的变量来表示。 中间件函数可以执行以下任务&#xff1a; 执行任何代码。对请求和响应对象进行更改。结束请求/响应循环。调用堆…

pytorch学习——循环神经网络RNN讲解及其实现

参考书籍&#xff1a;8.6. 循环神经网络的简洁实现 — 动手学深度学习 2.0.0 documentation 参考视频&#xff1a;54 循环神经网络 RNN【动手学深度学习v2】_哔哩哔哩_bilibili 一.介绍 循环神经网络RNN&#xff08;Recurrent Neural Network &#xff09;是一类广泛应用于序列…

stm32之30.DMA

DMA&#xff08;硬件加速方法&#xff09;一般用于帮运比较大的数据&#xff08;如&#xff1a;摄像头数据图像传输&#xff09;&#xff0c;寄存器-》DMA-》RAM 或者 RAM-》DMA-》寄存器提高CPU的工作效率 源码-- #include "myhead.h" #include "adc.h"#…

javaee之黑马乐优商城2

简单分析一下商品分类表的结构 先来说一下分类表与品牌表之间的关系 再来说一下分类表和品牌表与商品表之间的关系 面我们要开始就要创建sql语句了嘛&#xff0c;这里我们分析一下字段 用到的数据库是heima->tb_category这个表 现在去数据库里面创建好这张表 下面我们再去编…

有向图和无向图的表示方式(邻接矩阵,邻接表)

目录 一.邻接矩阵 1.无向图​编辑 2.有向图 补充&#xff1a;网&#xff08;有权图&#xff09;的邻接矩阵表示法 二.邻接表 1.无向图 2.有向图 三.邻接矩阵与邻接表的关系 一.邻接矩阵 1.无向图 &#xff08;1&#xff09;对角线上是每一个顶点与自身之间的关系&…

线性空间和线性变化

目录 考点一、线性空间的基与维数 1、线性空间 2、基底 3、子空间&#xff08;线性子空间&#xff09; ​编辑4、生成子空间 &#xff08;1&#xff09;、v1 n v2 &#xff08;2&#xff09;、v1 v2 5、求和子空间的方法 6、维数定理 7、例题 &#xff08;1&#xf…

HCIA自学笔记01-冲突域

共享式网络&#xff08;用同一根同轴电缆通信&#xff09;中可能会出现信号冲突现象。 如图是一个10BASE5以太网&#xff0c;每个主机都是用同一根同轴电缆来与其它主机进行通信&#xff0c;因此&#xff0c;这里的同轴电缆又被称为共享介质&#xff0c;相应的网络被称为共享介…

MyBatis-Plus学习笔记总结

一、查询 构造器分为QueryWrapper和LambdaQueryWrapper 创建实体类User package com.system.mybatisplus.model;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.…

JDK8的 ConcurrentHashMap 源码分析

目录 1. 导读 2. ConcurrentHashMap 成员变量解读 3. ConcurrentHashMap 初始化 3.1 ConcurrentHashMap 无参构造源码解读 3.2 ConcurrentHashMap 带参构造源码解读 3.3 tableSizeFor 方法作用解读 3.4 ConcurrenthashMap初始化总结 4. ConcurrentHashMap 添加元素方法…

springboot之一:配置文件(内外部配置优先顺序+properties、xml、yaml基础语法+profile动态切换配置、激活方式)

配置的概念&#xff1a; Spring Boot是基于约定的&#xff0c;所以很多配置都有默认值&#xff0c;但如果想使用自己的配置替换默认配置的话&#xff0c;就可以使用application.properties或者application.yml(application.yaml)进行配置。 注意配置文件的命名必须是applicat…

大数据课程K18——Spark的ALS算法与显式矩阵分解

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Spark的ALS算法与显式矩阵分解; ⚪ 掌握Spark的ALS算法原理; 一、ALS算法与显式矩阵分解 1. 概述 我们在实现推荐系统时,当要处理的那些数据是由用户所提供的自身的偏好数据,这些…

设计模式系列-原型模式

一、上篇回顾 上篇创建者模式中&#xff0c;我们主要讲述了创建者的几类实现方案&#xff0c;和创建者模式的应用的场景和特点&#xff0c;创建者模式适合创建复杂的对象&#xff0c;并且这些对象的每 个组成部分的详细创建步骤可以是动态的变化的&#xff0c;但是每个对象的组…

数据可视化、BI和数字孪生软件:用途和特点对比

在现代企业和科技领域&#xff0c;数据起着至关重要的作用。为了更好地管理和理解数据&#xff0c;不同类型的软件工具应运而生&#xff0c;其中包括数据可视化软件、BI&#xff08;Business Intelligence&#xff09;软件和数字孪生软件。虽然它们都涉及数据&#xff0c;但在功…

《TCP/IP网络编程》阅读笔记--域名及网络地址

目录 1--域名系统 2--域名与 IP 地址的转换 2-1--利用域名来获取 IP 地址 2-2--利用 IP 地址获取域名 3--代码实例 3-1--gethostbyname() 3-2--gethostbyaddr() 1--域名系统 域名系统&#xff08;Domain Name System&#xff0c;DNS&#xff09;是对 IP 地址和域名进行相…

2023/9/7 -- C++/QT

作业 1> 思维导图 2> 封装一个结构体&#xff0c;结构体中包含一个私有数组&#xff0c;用来存放学生的成绩&#xff0c;包含一个私有变量&#xff0c;用来记录学生个数&#xff0c; 提供一个公有成员函数&#xff0c;void setNum(int num)用于设置学生个数 提供一个…

✔ ★算法基础笔记(Acwing)(一)—— 基础算法(20道题)【java版本】

基础算法 一、快速排序1. 快速排序例题2. 第k个数( 快速选择 ) ✔ ✔1.31★快排二刷总结( 4点 ) 二、归并排序1. 归并排序模板题 ✔ ✔1.31★二刷总结 ★2. 逆序对的数量 ✔ ✔1.31★二刷总结 三、二分1. 数的范围 ✔1.31★二刷总结(mid > x 则是 输出最左边一个)第一个大于…