C#,图论与图算法,图(Graph)的数据结构设计与源代码

因为后面即将发布的大量有关“图”的算法与源代码都需要用到下面的这些基础数据,为避免大家去下载,特意先发布于此。

一、图(Graph)的基础知识

图(Graph)是一组对象的图示,其中一些对象对通过链接连接。互连对象由称为顶点的点表示,连接顶点的链接称为边。

形式上,图是一对集(V,E),其中V是顶点集,E是连接顶点对的边集。

图形数据结构

数学图可以用数据结构表示。我们可以使用顶点数组和二维边数组来表示图。在继续之前,让我们先熟悉一些重要的术语−

顶点− 图的每个节点都表示为一个顶点。在以下示例中,带标签的圆表示顶点。因此,A到G是顶点。我们可以使用下图所示的数组来表示它们。这里A可以通过索引0来标识。B可以使用索引1等进行识别。

− 边表示两个顶点之间的路径或两个顶点之间的线。在以下示例中,从A到B、B到C等的线表示边。我们可以使用二维数组来表示数组,如下图所示。这里AB可以表示为第0行第1列的1,BC可以表示为第1行第2列的1,依此类推,其他组合保持为0。

邻接关系− 如果两个节点或顶点通过边相互连接,则它们是相邻的。在以下示例中,B与A相邻,C与B相邻,依此类推。

路径− 路径表示两个顶点之间的边序列。

二、图的基本操作

以下是图形的基本主要操作:

添加顶点 — 将顶点添加到图形中。

添加边 — 在图形的两个顶点之间添加边。

显示顶点 — 显示图形的顶点。

遍历 — 深度优先遍历,宽度优先遍历;

布局 — 图的布局算法

三、图的相关数据

1、节点

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{/// <summary>/// 图的结点(坐标)信息/// </summary>public class Node{/// <summary>/// 编号/// </summary>public int Id { get; set; } = 0;/// <summary>/// X坐标/// </summary>public double X { get; set; } = 0.0;/// <summary>/// Y坐标/// </summary>public double Y { get; set; } = 0.0;//public int Weight { get; set; } = 0;/// <summary>/// 默认构造函数/// </summary>public Node() {}public Node(int id) {Id = id;}/// <summary>/// 长度(原点距离)/// </summary>public double Length{get{double len = LengthSquare;if (Math.Abs(len) < float.Epsilon) return 0.0;return Math.Sqrt(len);}}/// <summary>/// 长度平方/// </summary>public double LengthSquare{get{return (X * X) + (Y * Y);}}/// <summary>/// 缩放/// </summary>/// <param name="rate"></param>public void Scale(double rate){X *= rate;Y *= rate;}/// <summary>/// 移动到目的点/// </summary>/// <param name="x"></param>/// <param name="y"></param>public void MoveTo(double x, double y){X = x;Y = y;}/// <summary>/// 移动/// </summary>/// <param name="delta"></param>public void Move(Node delta){this.X += delta.X;this.Y += delta.Y;}/// <summary>/// 加号重载/// </summary>/// <param name="a"></param>/// <param name="b"></param>/// <returns></returns>public static Node operator +(Node a, Node b){Node c = new Node();c.X = a.X + b.X;c.Y = a.Y + b.Y;return c;}/// <summary>/// 减号重载/// </summary>/// <param name="a"></param>/// <param name="b"></param>/// <returns></returns>public static Node operator -(Node a, Node b){Node c = new Node();c.X = a.X - b.X;c.Y = a.Y - b.Y;return c;}}
}

2、边

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{public class Edge{/// <summary>/// 起点(第一点)编号/// </summary>public int First { get; set; } = -1;/// <summary>/// 终点(第二点)编号/// </summary>public int Second { get; set; } = -1;/// <summary>/// 权值/// </summary>public int Weight { get; set; } = 0;/// <summary>/// 默认构造函数/// </summary>public Edge(){}/// <summary>/// 两点构造函数/// </summary>/// <param name="f"></param>/// <param name="s"></param>public Edge(int f, int s){First = f;Second = s;}/// <summary>/// 两点及权值构造函数/// </summary>/// <param name="f"></param>/// <param name="s"></param>/// <param name="w"></param>public Edge(int f, int s, int w){First = f;Second = s;Weight = w;}}
}

3、图

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{public partial class Graph{/// <summary>/// 是否为有向图?/// </summary>public bool Direction { get; set; } = false;/*/// <summary>/// 节点编码的起始编号0或1/// </summary>public int Node_Index_Start { get; set; } = 0;/// <summary>/// 节点编码的结束编号/// </summary>public int Node_Index_End { get; set; } = 0;*//// <summary>/// 节点总数/// </summary>public int Node_Number { get; set; } = 0;/*/// <summary>/// 连线编码的起始编号0或1/// </summary>public int Edge_Start { get; set; } = 0;*//// <summary>/// 连接线总数/// </summary>public int Edge_Number { get; set; } = 0;/// <summary>/// 节点编码列表/// </summary>public List<Node> Nodes { get; set; } = new List<Node>();/// <summary>/// 连接线列表/// </summary>public List<Edge> Edges { get; set; } = new List<Edge>();/// <summary>/// 节点邻接表/// </summary>public List<int>[] Adjacency { get; set; } = null;/// <summary>/// 邻接矩阵/// </summary>public int[,] Matrix { get; set; } = null;public Graph(){}public Graph(int v, int e = 0, bool direct = false){Direction = direct;Node_Number = v;Edge_Number = e;Adjacency = new List<int>[Node_Number + 1];for (int i = 0; i <= Node_Number; i++){Adjacency[i] = new List<int>();}}public void AddEdge(int a, int b){Adjacency[a].Add(b);if (Direction == false){Adjacency[b].Add(a);}}public void AddEdge(int a, int b, int w){AddEdge(a, b);Edges.Add(new Edge(a, b, w));}public void AddEdge(int idx, int a, int b, int w){Edges[idx] = new Edge(a, b, w);}public void AddNode(int a){if (!Nodes.Exists(t => t.Id == a)){Nodes.Add(new Node(a));}}/// <summary>/// 按三元组构造图数据/// 三元数组为: {source,destination,weight}/// </summary>/// <param name="ternary_array">三元数据</param>public Graph(int[,] ternary_array, bool dir = false){// 有向图?无向图?Direction = dir;Nodes = new List<Node>();Edges = new List<Edge>();Edge_Number = ternary_array.GetLength(0);for (int i = 0; i < ternary_array.GetLength(0); i++){int n1 = ternary_array[i, 0];int n2 = ternary_array[i, 1];int wt = ternary_array[i, 2];AddEdge(n1, n2, wt);}}/// <summary>/// 按关联矩阵数据构建图/// [N x N],元素=0,无连接,>0 有连接线及weight/// </summary>/// <param name="v">节点数</param>/// <param name="e">连边数</param>/// <param name="matrix">关联矩阵</param>public Graph(int[,] matrix){Node_Number = matrix.GetLength(0);Nodes = new List<Node>();Edges = new List<Edge>();Matrix = new int[Node_Number, Node_Number];for (int i = 0; i < Node_Number; i++){for (int j = 0; j < Node_Number; j++){if (matrix[i, j] > 0){AddEdge(i, j, matrix[i, j]);Matrix[i, j] = matrix[i, j];}}}}public Edge FindEdge(int a, int b){foreach (Edge e in Edges){if (e.First == a && e.Second == b){return e;}if (Direction == false){if (e.First == b && e.Second == a){return e;}}}return null;}/// <summary>/// 按邻接表的构造函数/// </summary>/// <param name="adj"></param>public Graph(List<List<int>> adj, bool dir = false){// 有向图?无向图?Direction = dir;Node_Number = adj.Count;Nodes = new List<Node>();Edges = new List<Edge>();// 邻接矩阵Adjacency = adj.ToArray();int idx = 1;foreach (List<int> xu in adj){foreach (int xv in xu){AddEdge(idx, xv);}idx++;}}/// <summary>/// 邻接表 转为 邻接矩阵/// 1 起步!/// </summary>/// <returns></returns>public int[,] AdjacencyMatrix(){if (Matrix == null){Matrix = new int[Node_Number + 1, Node_Number + 1];int idx = 0;foreach (List<int> xu in Adjacency){// 因为 Adjacency[0] 没有被使用!跳过!if (idx > 0){foreach (int xv in xu){Matrix[idx, xv] = 1;}}idx++;}}return Matrix;}}
}

POWER BY TRUFFER.CN

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

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

相关文章

STM32(TIM定时器中断)

理论知识 定时器定时中断 接线图 定时器工作配置步骤 定时中断和内外时钟源选择 定时器中需要使用的函数 程序实现效果&#xff1a; void TIM_DeInit(TIM_TypeDef* TIMx); **// 恢复定时器的缺省配置**void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef*TIM…

【C++】每日一题 228 汇总区间

给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属于某个范围但不属于 nums 的数字 x 。 列表中的每个区间范围 [a,b] 应该按…

SeAndroid 安全策略机制

seAndroid 是 Android 系统中 SELinux&#xff08;Security-Enhanced Linux&#xff09;的实现&#xff0c;它为 Android 提供了强制访问控制&#xff08;MAC&#xff09;机制。在 seAndroid 中&#xff0c;策略规则定义了不同进程和文件之间的交互方式&#xff0c;以确保系统的…

数据可视化-ECharts Html项目实战(2)

在之前的文章中&#xff0c;我们学习了如何创建简单的折线图&#xff0c;条形图&#xff0c;柱形图并实现动态触发&#xff0c;最大最小平均值。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下…

波奇学Linux:线程安全和自选锁和读写锁

STL不是线程安全的 单例模式的线程安全 自选锁&#xff1a;当线程申请锁失败时&#xff0c;不是挂起&#xff0c;而是一直申请 挂起等待锁 &#xff1a;当线程申请锁失败时&#xff0c;把锁挂起 一般临界区时间短的适合自选锁&#xff0c;长的适合挂起等待锁

Unity的AssetBundle资源运行内存管理的再次深入思考

大家好&#xff0c;我是阿赵。   这篇文章我想写了很久&#xff0c;是关于Unity项目使用AssetBundle加载资源时的内存管理的。这篇文章不会分享代码&#xff0c;只是分享思路&#xff0c;思路不一定正确&#xff0c;欢迎讨论。   对于Unity引擎的资源内存管理&#xff0c;我…

Visual Studio项目模板的创建与使用

Visual Studio项目模板的创建、使用、删除 创建模板项目模板的使用模板的删除 创建模板 点击项目&#xff0c;点击导出模板 选择你要创建哪个项目的项目模板&#xff0c;点击下一步 输入你的模板名称并添加模板说明&#xff0c;方便记忆 项目模板的使用 点击创建新项目 输入刚刚…

[长城杯 2021 院校组]funny_js

[长城杯 2021 院校组]funny_js 审题 根据题名提示为js&#xff0c;再在ida中查看&#xff0c;基本可以确定为quickjs题 QuickJS 是一个快速、灵活且易于嵌入的 JavaScript 引擎&#xff0c;适用于需要在资源受限环境下运行 JavaScript 代码的场景。 工具准备 来到Linux&…

Qt QTableWidget 实现行选中及行悬浮高亮

表格整行的 selected、hover 高亮需求很常见&#xff0c;但使用 Qt 提供的开箱即用的方法根本无法实现这个需求&#xff08;至少在当前的时间节点是不行的&#xff09;&#xff1b;想要实现这个效果必须要费一点点力气&#xff0c;我们尽量选择较为简单的方法。 话不多说&…

高可用系统有哪些设计原则

1.降级 主动降级&#xff1a;开关推送 被动降级&#xff1a;超时降级 异常降级 失败率 熔断保护 多级降级2.限流 nginx的limit模块 gateway redisLua 业务层限流 本地限流 gua 分布式限流 sentinel 3.弹性计算 弹性伸缩—K8Sdocker 主链路压力过大的时候可以将非主链路的机器给…

Linux rhmask命令教程:管理Red Hat系统中的掩码(附案例详解和注意事项)

Linux rhmask命令介绍 rhmask是一个用于管理Red Hat系统中的掩码的命令。它可以帮助用户查看、设置和删除系统中的掩码。掩码是一种用于控制文件权限的机制&#xff0c;通过设置掩码&#xff0c;用户可以控制新创建的文件或目录的默认权限。 Linux rhmask命令适用的Linux版本…

python内置函数 C

python内置函数 C Python 解释器内置了很多函数和类型&#xff0c;任何时候都能使用。 C 名称描述callable检查一个对象是否是可调用的。chr将整数&#xff08;表示Unicode码点&#xff09;转换为对应的字符。classmethod将一个方法转变为类方法。compile将源代码字符串编译…

Task-balanced distillation for object detection用于

Task-balanced distillation for object detection用于目标检测的任务平衡蒸馏 摘要 主流的目标检测器通常由分类和回归两个子任务组成&#xff0c;由两个并行头部实现。这种经典的设计范式不可避免的导致分类得分和定位质量&#xff08;IOU&#xff09;之间的空间分布不一致…

【CTF web1】

CTF web 一、CTF web -PHP弱类型1、是否相等&#xff1f;2、转换规则: 二、CTF web -md5绕过1、若类型比较绕过2、null绕过3、碰撞绕过 三、习题 一、CTF web -PHP弱类型 1、是否相等&#xff1f; &#xff1a;在进行比较的时候&#xff0c;会先判断两种字符串的类型是否相等&…

深入探讨GPT系列与其他NLP架构的流行度差异及其应用解析

Transformer问答-1 为什么现在GPT系列的decoder-only那么流行&#xff0c;而其它两者:encoder-only和encoder-decoder架构不流行了呢? GPT系列&#xff08;特别是从GPT-3开始&#xff09;的流行并不意味着encoder-only或encoder-decoder架构不再流行或不再重要。事实上&…

2024.3.13-408学习笔记-C-数据在内存中的存储

1、整数型存储 整数型存储就是所有整型家族里的数据类型的存储方式&#xff0c;也就是说包含了字符类型的存储&#xff08;因为字符的操作符的返回值是ASCII码值&#xff0c;故实际上存储的是整数&#xff09;。 1.1、有符号整数 有符号整数包含char&#xff0c;short&#…

切面条-蓝桥杯?-Lua 中文代码解题第1题

切面条-蓝桥杯&#xff1f;-Lua 中文代码解题第1题 一根高筋拉面&#xff0c;中间切一刀&#xff0c;可以得到2根面条。 如果先对折1次&#xff0c;中间切一刀&#xff0c;可以得到3根面条。 如果连续对折2次&#xff0c;中间切一刀&#xff0c;可以得到5根面条。 那么&#xf…

【ollama】(7):使用Nvidia Jetson Nano设备,成功运行ollama,运行qwen:0.5b-chat,速度还可以,可以做创新项目了

1&#xff0c;视频地址 https://www.bilibili.com/video/BV1Pj421o7W5/ 【ollama】&#xff08;7&#xff09;&#xff1a;使用Nvidia Jetson Nano设备&#xff0c;成功运行ollama&#xff0c;运行qwen:0.5b-chat&#xff0c;速度还可以&#xff0c;可以做创新项目了 2&#x…

vuex购物车案例

store/index.js // 导入vue import Vue from vue // 导入vuex import Vuex from vueximport cart from ./module/cartVue.use(Vuex)// 创建仓库store const store new Vuex.Store({strict: true,modules: {cart} })// 导出仓库 export default storestore/modules/cart impo…

Rust的async和await支持多线程运行吗?

Rust的async和await的异步机制并不是仅在单线程下实现的&#xff0c;它们可以在多线程环境中工作&#xff0c;从而利用多核CPU的并行计算优势。然而&#xff0c;异步编程的主要目标之一是避免不必要的线程切换开销&#xff0c;因此&#xff0c;在单线程上下文中&#xff0c;asy…