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语言 大话数据结构——图相关推荐

  1. 【数据结构(C语言)】数据结构-图

    图 文章目录 图 一.基本概念 1.图的定义 2.约定符号 3.分类 4.子图 5.路 6.其他术语 7.ADT 二.存储结构 1.邻接矩阵(数组) 2.邻接表 三.基本算法 1.遍历 2.求无向图的 ...

  2. 四色着色问题 c语言编程,数据结构-图着色问题

    7-38 图着色问题 (25 分) 图着色问题是一个著名的NP完全问题.给定无向图G=(V,E),问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要 ...

  3. 大话数据结构及JAVA数据结构阅读笔记

    目录 一.大话数据结构随书阅读笔记 第一章 数据结构概述 第二章  算法概述 第三章 线性表 第四章 栈与队列 第五章 串 第六章 树 第七章 图 第八章 查找 第九章 排序 二.大话数据结构思维导图 ...

  4. 【数据结构(C语言)】数据结构-表

    数据结构-表 [知识索引][数据结构(C语言)] 一.线性表 (1)基本概念 1.定义(性质相同的数据元素构成的有限序列) 2.表长,空表,位序,直接前驱,直接后继 3.基本操作(12) (2)存储结 ...

  5. 【数据结构(C语言)】数据结构-内部排序

    内部排序 文章目录 内部排序 一.概述 (1)排序定义 (2)稳定性 (3)内部排序和外部排序 (4)两种基本操作 (5)数据类型定义 二.分类 (1)插入排序 (2)交换排序 (3)选择排序 (4) ...

  6. 【数据结构(C语言)】数据结构-查找

    查找 文章目录 查找 一.基本概念 1.查找表 2.关键字 3.查找 二.查找算法的性能分析 1.平均查找长度(Average Search Length) 三.基于线性表的查找 1.存储结构的定义 ...

  7. 【数据结构(C语言)】数据结构-树

    树 文章目录 树 一.基本概念 1.树的定义 2.树的节点 3.树的性质 4.基本操作 二.二叉树 1.二叉树的特点 2.特殊二叉树 3.性质 4.存储结构 (1)二叉链表 (2)三叉链表 5.线索化 ...

  8. 大话数据结构读书笔记艾提拉总结 查找算法 和排序算法比较好 第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 第 ...

  9. 《大话数据结构》读书笔记-图

    写在前面:本文仅供个人学习使用.<大话数据结构>通俗易懂,适合整体做笔记输出,构建体系.并且文中很多图片来源于该书,如有侵权,请联系删除. 文章目录 7.2 图的定义 7.2.1 各种图定 ...

最新文章

  1. psnr 与 ssim评测步骤
  2. Science:人类在实验室创建了微型“大脑”,含祖先基因的那种
  3. 青龙面板薅羊毛–都爱玩(日收益2元左右)
  4. LVS(7)——NAT实践
  5. HTML入门第一和第二章
  6. nacis服务注册原理_HwServiceManager篇Android10.0 HwBinder通信原理(五)
  7. SharePoint 2013 Step by Step——使用自定义的List Template
  8. feignclient注解使用_Spring Cloud Nacos的使用
  9. APP性能测试之帧率测试
  10. linux工具apt、yum和dnf运用
  11. 关联本地项目和svn_技术贴 本地代码与svn关联教程 svn upgrade问题解决
  12. 当下最强的 AI art 生成模型 Stable Diffusion 最全面介绍
  13. 有道云笔记同步失败原因之一
  14. python如何学 Python主要能做什么
  15. ubuntu20.04安装小鹤双拼输入法挂接音形改简体中文Rime
  16. 2008最强哲理网络语录
  17. python 生涯之语法基础
  18. MySQL命令简单应用
  19. 应用fiddler,使用har2case 将api参数转成yaml格式
  20. 简单明了的正则表达式汇总

热门文章

  1. python entry如何清空_如何清除tkinter中来自Entry小部件的以前输入?
  2. k8s集群coredns无法解析外部域名
  3. 飞扬的小鸟JavaScript实现
  4. 离线语音蓝牙设计应用案例
  5. mt4下载正版官网下载(如何分辨真假MT4软件)
  6. Keras教学(1):Keras是什么
  7. 2018年全国多校算法寒假训练营练习比赛(第二场)H 了断局
  8. 直播app开发解决方案
  9. horizon流程图_致同Horizon审计方法论.pdf
  10. 人体红外传感器HC-SR501