Go语言 大话数据结构——图
1、名词解释:
图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。在图中的数据元素,我们称之为顶点(Vertex),顶点集合有穷非空。在图中,任意两个顶点之间都可能有关系,顶点之间的逻辑关系用边来表示,边集可以是空的。
图按照边的有无方向分为无向图和有向图。无向图由顶点和边组成,有向图由顶点和弧构成。弧有弧尾和弧头之分,带箭头一端为弧头。
图按照边或弧的多少分稀疏图和稠密图。如果图中的任意两个顶点之间都存在边叫做完全图,有向的叫有向完全图。若无重复的边或顶点到自身的边则叫简单图。
图中顶点之间有邻接点、依附的概念。无向图顶点的边数叫做度。有向图顶点分为入度和出度。
图上的边或弧带有权则称为网。
图中顶点间存在路径,两顶点存在路径则说明是连通的,如果路径最终回到起始点则称为环,当中不重复的叫简单路径。若任意两顶点都是连通的,则图就是连通图,有向则称为强连通图。图中有子图,若子图极大连通则就是连通分量,有向的则称为强连通分量。
无向图中连通且n个顶点n-1条边称为生成树。有向图中一顶点入度为0其余顶点入度为1的叫有向树。一个有向图由若干棵有向树构成生成森林。
2、图的存储结构—-邻接矩阵
图的邻接矩阵的表示方式需要两个数组来表示图的信息,一个一维数组表示每个数据元素的信息,一个二维数组(邻接矩阵)表示图中的边或者弧的信息。
如果图有n个顶点,那么邻接矩阵就是一个n*n的方阵,方阵中每个元素的值的计算公式如下:
邻接矩阵表示图的具体示例如下图所示:
首先给个无向图的实例:
下面是一个有向图的实例:
OK,到这里为止,我们给出一个无向图的邻接矩阵和一个有向图的邻接矩阵,我们可以从这两个邻接矩阵得出一些结论:
- 无向图的邻接矩阵都是沿对角线对称的
- 要知道无向图中某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
- 对于有向图,要知道某个顶点的出度,其实就是这个顶点vi在邻接矩阵中第i行的元素之和,如果要知道某个顶点的入度,那就是第i列的元素之和。
但是,如果我们需要表示的图是一个网的时候,例如假设有个图有n个顶点,同样该网的邻接矩阵也是一个n*n的方阵,只是方阵元素的值的计算方式不同,如下图所示:
这里的wij表示两个顶点vi和vj边上的权值。无穷大表示一个计算机允许的、大于所有边上权值的值,也就是一个不可能的极限值。下面是具体示例,表示的一个有向网的图和邻接矩阵:
实例代码:
package mainimport ("fmt"
)type VertexType string //定义顶点的数据类型
type EdgeType int //边的类型
const MAXVEX = 100 //最大的顶点数
const MAXVALUE = 65535 //无效数 (无穷大,也就是说此边不通)type MGraph struct {vexs [MAXVEX]VertexType //定义一个数组,保存对应的顶点,可以保存65535个顶点arc [MAXVEX][MAXVEX]int //定义一个二维数组,保存顶点对应的边,二维数组可以保存[65535][65535]numVer, numEdg int //边的数量,顶点的数量isTrav [MAXVEX] bool //设定某个节点是否遍历过,主要用于节点的遍历GType byte //定义图的类型,0:无向图 1:有向图
}/*创建图:
*/
func createMGraph(mg *MGraph) {fmt.Println("请输入顶点数:")fmt.Scan(&mg.numVer)for i := 0; i < mg.numVer; i++ {fmt.Printf("请输入第%d个顶点:\n", i+1)var tempChar VertexTypefmt.Scan(&tempChar)mg.vexs[i] = tempChar//fmt.Print("\n输入的内容为:", mg.vexs[i])}//顶点组成边,初始化for i := 0; i < mg.numVer; i++ {for j := 0; j < mg.numVer; j++ {mg.arc[i][j] = MAXVALUE}}fmt.Println("请输入边数:")fmt.Scan(&mg.numEdg)for i := 0; i < mg.numEdg; i++ {//fmt.Println("请分别输入坐标E(i,j)以及权重")fmt.Printf("请输入第%d条边的坐标E(i,j)以及权重\n", i+1)var i, j, weight intfmt.Scan(&i)fmt.Scan(&j)fmt.Scan(&weight)mg.arc[i][j] = weightif mg.GType == 0 {mg.arc[j][i] = weight //无向图:数据依据对角线对称}//fmt.Printf("输入的权重为:%d", mg.arc[i][j])}/*for i := 0; i < mg.numVer; i++ {for j := i; j < mg.numVer; j++ {fmt.Println("----------")fmt.Println(mg.arc[i][j])//fmt.Println(mg.arc[j][i])}}for i := 0; i < mg.numEdg; i++ {fmt.Println(mg.vexs[i])}*/
}/*清空图:1)清空边对应的权重 2)清空顶点组成的数组
*/
func ClearGraph(mg *MGraph) {for i := 0; i < mg.numVer; i++ {for j := 0; j < i; j++ {mg.arc[i][j] = MAXVALUE}}for i := 0; i < mg.numVer; i++ {mg.vexs[i] = ""}
}
func ShowGraph(mg *MGraph) {fmt.Println()for i := 0; i < mg.numVer; i++ {fmt.Printf("\t\t%s", mg.vexs[i])}fmt.Println()for i := 0; i < mg.numVer; i++ {fmt.Printf("%s\t\t", mg.vexs[i])for j := 0; j < mg.numVer; j++ {if mg.arc[i][j] == MAXVALUE {fmt.Printf("%s\t\t", "Z")} else {fmt.Printf("%d\t\t", mg.arc[i][j])}}fmt.Println()}}/*
图的遍历:遍历图就是逐个访问图中的所有节点
深度优先遍历算法思想:
1)从数组isTrav中选择一个未被遍历的顶点V(Vi),将其标记为true,表示已经访问过。
2)从Vi的一个未被访问的邻接点出发进行深度优先遍历;
3)重复 2),直至图中的所用和Vi有路径相通的顶点都被访问过。
4)重复1)-3)的操作,直到图中所用节点都被访问过
*//*fun:从第 n个节点开始,深度遍历图
*/
func DeepTraOne(mg *MGraph, n int) {mg.isTrav[n] = truefmt.Print("---->", mg.vexs[n])for i := 0; i < mg.numVer; i++ {if mg.arc[n][i] != MAXVALUE && mg.isTrav[n] != true {DeepTraOne(mg, i)}}
}/*fun:通过 DeepTraOne()函数,遍历所有的节点
*/
func DeepTraGraph(mg *MGraph) {//清除遍历标志位for i := 0; i < mg.numVer; i++ {mg.isTrav[i] = false}for i := 0; i < mg.numVer; i++ {if mg.isTrav[i] == false {DeepTraOne(mg, i)}}fmt.Println()}
func main() {mg := MGraph{}createMGraph(&mg)ShowGraph(&mg)fmt.Println("遍历图:")DeepTraGraph(&mg)}
运行效果:
注:图的类型没有设置,默认为无向图。如果要设置,添加 mg.GType=1即可。
Go语言 大话数据结构——图相关推荐
- 【数据结构(C语言)】数据结构-图
图 文章目录 图 一.基本概念 1.图的定义 2.约定符号 3.分类 4.子图 5.路 6.其他术语 7.ADT 二.存储结构 1.邻接矩阵(数组) 2.邻接表 三.基本算法 1.遍历 2.求无向图的 ...
- 四色着色问题 c语言编程,数据结构-图着色问题
7-38 图着色问题 (25 分) 图着色问题是一个著名的NP完全问题.给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要 ...
- 大话数据结构及JAVA数据结构阅读笔记
目录 一.大话数据结构随书阅读笔记 第一章 数据结构概述 第二章 算法概述 第三章 线性表 第四章 栈与队列 第五章 串 第六章 树 第七章 图 第八章 查找 第九章 排序 二.大话数据结构思维导图 ...
- 【数据结构(C语言)】数据结构-表
数据结构-表 [知识索引][数据结构(C语言)] 一.线性表 (1)基本概念 1.定义(性质相同的数据元素构成的有限序列) 2.表长,空表,位序,直接前驱,直接后继 3.基本操作(12) (2)存储结 ...
- 【数据结构(C语言)】数据结构-内部排序
内部排序 文章目录 内部排序 一.概述 (1)排序定义 (2)稳定性 (3)内部排序和外部排序 (4)两种基本操作 (5)数据类型定义 二.分类 (1)插入排序 (2)交换排序 (3)选择排序 (4) ...
- 【数据结构(C语言)】数据结构-查找
查找 文章目录 查找 一.基本概念 1.查找表 2.关键字 3.查找 二.查找算法的性能分析 1.平均查找长度(Average Search Length) 三.基于线性表的查找 1.存储结构的定义 ...
- 【数据结构(C语言)】数据结构-树
树 文章目录 树 一.基本概念 1.树的定义 2.树的节点 3.树的性质 4.基本操作 二.二叉树 1.二叉树的特点 2.特殊二叉树 3.性质 4.存储结构 (1)二叉链表 (2)三叉链表 5.线索化 ...
- 大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 21
大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第1章数据结构绪论 1 第2章算法 17 第3章线性表 41 第4章栈与队列 87 第5章串 123 第6章树 149 第7章图 211 第 ...
- 《大话数据结构》读书笔记-图
写在前面:本文仅供个人学习使用.<大话数据结构>通俗易懂,适合整体做笔记输出,构建体系.并且文中很多图片来源于该书,如有侵权,请联系删除. 文章目录 7.2 图的定义 7.2.1 各种图定 ...
最新文章
- psnr 与 ssim评测步骤
- Science:人类在实验室创建了微型“大脑”,含祖先基因的那种
- 青龙面板薅羊毛–都爱玩(日收益2元左右)
- LVS(7)——NAT实践
- HTML入门第一和第二章
- nacis服务注册原理_HwServiceManager篇Android10.0 HwBinder通信原理(五)
- SharePoint 2013 Step by Step——使用自定义的List Template
- feignclient注解使用_Spring Cloud Nacos的使用
- APP性能测试之帧率测试
- linux工具apt、yum和dnf运用
- 关联本地项目和svn_技术贴 本地代码与svn关联教程 svn upgrade问题解决
- 当下最强的 AI art 生成模型 Stable Diffusion 最全面介绍
- 有道云笔记同步失败原因之一
- python如何学 Python主要能做什么
- ubuntu20.04安装小鹤双拼输入法挂接音形改简体中文Rime
- 2008最强哲理网络语录
- python 生涯之语法基础
- MySQL命令简单应用
- 应用fiddler,使用har2case 将api参数转成yaml格式
- 简单明了的正则表达式汇总