图的定义

图(Graph)——图G是由两个集合V(G)和E(G)组成的,记为G=(V,E)其中:V(G)是顶点的非空有限集,E(G)是边的有限集合,边是顶点的无序对或有序对。

有向图——有向图G是由两个集合V(G)和E(G)组成
其中:V(G)是顶点的非空有限集,E(G)是有向边(也称弧)的有限集合,弧是顶点的有序对,记为<v,w>,v,w是顶点,v为弧尾,w为弧头

无向图——无向图G是由两个集合V(G)和E(G)组成
其中:V(G)是顶点的非空有限集,E(G)是边的有限集合,边是顶点的无序对,记为(v,w)或(w,v),并且(v,w)=(w,v)。

有向完全图——n个顶点的有向图最大边数是n(n-1)
无向完全图——n个顶点的无向图最大边数是n(n-1)/2

——与图的边或弧相关的数

——带权的图

顶点的度

  • 无向图中,顶点的度为与每个顶点相连的边数;
  • 有向图中,顶点的度分成入度与出度;
  • 入度:以该顶点为头的弧的数目;
  • 出度:以该顶点为尾的弧的数目;

路径——路径是顶点的序列V={Vi0,Vi1,……Vin},满足(Vij-1,Vij)∈E 或 < Vij-1,Vij>∈E,(1<j≦n)

路径长度——沿路径边的数目或沿路径各边权值之和

回路——第一个顶点和最后一个顶点相同的路径

简单路径——序列中顶点不重复出现的路径

简单回路——除了第一个顶点和最后一个顶点外,其余顶点不重复出现的回路

连通——从顶点V到顶点W有一条路径,则说V和W是连通的

连通图——图中任意两个顶点都是连通部分

连通分量——非连通图的每一个连通部分

强连通图——有向图中,如果对每一对Vi,VjV, ViVj,从Vi到Vj 和从Vj到 Vi都存在路径。

常用图的存储结构

1.邻接矩阵法——表示顶点间相联关系的矩阵

特点:

  1. 无向图的邻接矩阵对称,可压缩存储;有n个顶点的无向图需存储空间为n(n+1)/2;
  2. 有向图邻接矩阵不一定对称;有n个顶点的有向图需存储空间为n²;
  3. 无向图中顶点Vi的度TD(Vi)是邻接矩阵A中第i行元素之和;
  4. 有向图中, 顶点Vi的出度是A中第i行元素之和; 顶点Vi的入度是A中第i列元素之和;

2.邻接表法

实现:为图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点Vi的边(有向图中指以Vi为尾的弧)

特点:

  1. 无向图中顶点Vi的度为第i个单链表中的结点数;
  2. 有向图中 顶点Vi的出度为第i个单链表中的结点个数;顶点Vi的入度为整个单链表中邻接点域值是i的结点个数;
  3. 逆邻接表:有向图中对每个结点建立以Vi为头的弧的单链表;

图的基础操作

这里我采用的是邻接链表存储结构。图的遍历不管是广度遍历还是深度和树的遍历过程都非常相似,在这里我就很简单概述一下我的思路,如果不理解可以好好看一下我的另一篇文章------ 数据结构:树和二叉树(基础概念操作图文解释)同时不论是深度遍历还是广度遍历都需要辅助空间来标记某结点是否被访问过。

生成邻接链表

这里的代码很简单,唯一值得注意的是find函数以及输入的关系声明为char x,y;这里只是为了让整个程序有更好的适应性,即无论这个关系是数字与数字之间还是字母与字母之间程序都可以很好的运行。

int find(int n,char v)//求v在表头数组中的下标
{for(int i=1;i<=n;i++)if(m[i].data==v)return i;return -1;
}void creat(int n1,int n2)//生成邻接表
{char x,y;int z,n;jd* p;getchar();//吸收回车for(int i=0;i<n2;i++){cin>>x>>y;getchar();z=find(n1,x);n=find(n1,y);p=(jd*)malloc(sizeof(jd));p->id=z;p->next=m[n].firstnode;//头插 m[n].firstnode=p;p=(jd*)malloc(sizeof(jd));p->id=n;p->next=m[z].firstnode;m[z].firstnode=p;}
}

深度遍历

思路: 每次先访问表头的第一个孩子结点,若未访问过,则访问这个以这个孩子结点为表头的第一个孩子节点,若访问过,则访问它的第二个孩子结点······,这个过程非常类似于数的深度遍历不断访问左孩子过程。

void dfs(int v,int visit[10])//深度遍历
{visit[v]=1;//标记访问过的位置jd* w;w=m[v].firstnode;//访问v结点的第一个孩子节点cout<<v;while(w!=NULL)//解决某结点分叉 {if(!visit[w->id])//如果w->id未访问过继续递归进入下一层dfs(w->id,visit);w=w->next;//如果访问过就访问w->id的兄弟节点}
}

广度遍历

思路: 顺序访问起始表头(这个表头是随意的)的所有孩子结点,入队列,按队列的存储顺序访问相应表头的所有孩子结点,相当于树的层次遍历。

void bfs(int v,int visit[10])//广度遍历
{visit[v]=1;//标记起始节点jd* w;queue<int> q;//声明对列q.push(v);//起始结点入队 while(!q.empty()){v=q.front();//取队头结点cout<<v;q.pop();//删除(更新)队头元素 w=m[v].firstnode;//访问v结点第一个孩子结点while(w!=NULL)//遍历与某一个元素所有有关系的结点 {if(!visit[w->id])//若此结点未被遍历过则入队 {q.push(w->id);//w->id结点入队visit[w->id]=1;//标记w->id结点}w=w->next;//访问w的兄弟结点}}
}

图的连通性问题

思路: 如果一个图的所有结点都是连通的,那么for循环里的代码就只会执行一次,如果有多个连通分量,那么当一个连通分量的所有结点遍历完成后必然会进入for循环,然后继续遍历下一个连通分量,直到所有的结点都遍历完。

int travel(int n)
{int visit[10],sum=0;for(int j=1;j<10;j++)//初始化辅助数组为未访问状态visit[j]=0;for(int j=1;j<=n;j++)//连通性问题的核心{if(visit[j]==0){bfs(j,visit);sum++; }}return sum;
}

完整代码

#include <iostream>
#include <malloc.h>
#include <queue>
using namespace std;
typedef struct node//结点
{int id;struct node* next;
}jd;typedef struct head//表头
{char data;struct node* firstnode;
}td;td m[10];int find(int n,char v)
{for(int i=1;i<=n;i++)if(m[i].data==v)return i;return -1;
}void creat(int n1,int n2)//生成邻接表
{char x,y;int z,n;jd* p;getchar();for(int i=0;i<n2;i++){cin>>x>>y;getchar();z=find(n1,x);n=find(n1,y);p=(jd*)malloc(sizeof(jd));p->id=z;p->next=m[n].firstnode;//头插 m[n].firstnode=p;p=(jd*)malloc(sizeof(jd));p->id=n;p->next=m[z].firstnode;m[z].firstnode=p;}
}void dfs(int v,int visit[10])//深度遍历
{visit[v]=1;jd* w;w=m[v].firstnode;cout<<v;while(w!=NULL)//解决某结点分叉 {if(!visit[w->id])dfs(w->id,visit);w=w->next;}
}void bfs(int v,int visit[10])
{visit[v]=1;jd* w;queue<int> q;q.push(v);//起始结点入队 while(!q.empty()){v=q.front();cout<<v;q.pop();//删除队头元素 w=m[v].firstnode;while(w!=NULL)//遍历与某一个元素所有有关系的结点 {if(!visit[w->id])//若此结点未被遍历过则入队 {q.push(w->id);visit[w->id]=1;}w=w->next;}}
} int travel(int n)
{int visit[10],sum=0;for(int j=1;j<10;j++)visit[j]=0;for(int j=1;j<=n;j++){if(visit[j]==0){bfs(j,visit);sum++; }}return sum;
}
int main()
{int n1,n2,visit[10]={0},s,e;char d;cin>>n1>>n2;for(int i=1;i<=n1;i++)//初始化表头 {cin>>m[i].data;m[i].firstnode=NULL;}creat(n1,n2);int m=travel(n1);cout<<m;bfs(1,visit);return 0;
}

小结

本篇博客讲的都是图最基本的概念和操作以及本人自己的一点理解,希望这篇博客能够帮助到屏幕前的小伙伴!!!

数据结构:图(基础概念及操作,图文解释)相关推荐

  1. 数据结构——图——基础——总结:

    目录 图(Graph) 完全无向图: 完全有向图: 权(Weight): 子图和生成子图: 邻接点: 度: 生成树.生成森林: 关于无向图的生成树的几个结论: 网: 图的存储结构: 十字链表的画法 基 ...

  2. Rundeck基础:3:基础概念:操作Project

    Rundeck是一个基于Java和Grails的开源的运维自动化工具,提供了Web管理界面进行操作,同时提供命令行工具和WebAPI的访问控制方式.在这篇文章中,介绍一下基本概念和操作Project的 ...

  3. 图数据库入门教程-深入学习Gremlin(1):图基本概念与操作

    前言:Gremlin语言是图数据库最主流的查询语言,是Apache TinkerPop框架下规范的图语言,相当于SQL之于关系型数据库.为了图数据库使用者更好的掌握Gremlin这门图语言,我们对Gr ...

  4. 【java之路】4.基础概念与操作学习

    在C语言的基础上对Java基础知识与操作进行比较学习. 目录 调整注释样式 标识符(变量)命名 数据类型 基本数据类型 整数类型 浮点类型 字符类型 bool类型 引用数据类型 变量使用 基本操作 调 ...

  5. 数据结构——图基本概念

    图的基本概念 线性表中的元素是"一对一"的关系,树中的元素是"一对多"的关系,本章所述的图结构中的元素则是"多对多"的关系.图(Graph) ...

  6. 什么是ER图?数据库ER图基础概念整理

    前置知识 概述:数据模型的基本概念 模型就是对现实世界特征的模拟和抽象,数据模型是对现实世界数据特征的抽象.对于具体的模型人们并不陌生,如航模飞机.地图和建筑设计沙盘等都是具体的模型.最常用的数据模型 ...

  7. 数据库E-R图基础概念

    E-R图也称实体-联系图(Entity Relationship Diagram),提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型. ER模型的基本元素 实体:用方框表示,实体名为名 ...

  8. Rundeck基础:5:基础概念:操作操作Command与Execution

    上篇文章介绍了如何在Rundeck中进行添加Node,这篇文章继续介绍如何在添加的Node上进行Command的执行以及结果的确认. Comannd vs Job Job在使用上更接近于运维的例行作业 ...

  9. mysql er概念_数据库ER图基础概念

    ER图分为实体.属性.关系三个核心部分.实体是长方形体现,而属性则是椭圆形,关系为菱形. ER图的实体(entity)即数据模型中的数据对象,例如人.学生.音乐都可以作为一个数据对象,用长方体来表示, ...

  10. mysql er 图_数据库ER图基础概念整理

    ER图分为实体.属性.关系三个核心部分 图形表示分别是 长方形,椭圆形,菱形 一,组成部分介绍 1,实体(entity):数据模型中的数据对像,每个实体都有自己的实体成员或者说实体对象,例如学生实体包 ...

最新文章

  1. 生成对抗网络(GAN)
  2. 最先进数据中心都建在哪?
  3. python爬虫吧-Python爬虫案例集合
  4. 怎么开启JavaScript ?
  5. Linux 配置JAVA_HOME
  6. ODPS2.0重装上阵,优化提升SQL语言表达能力
  7. 算法复习第四章动态规划
  8. 腾讯数据库专家多年运维经验凝聚成简,总结这份595页工作笔记
  9. c#仿照qq登录界面编辑框内容操作
  10. CStatic类简介
  11. 什么是服务的熔断降级
  12. springmvc配置中文乱码过滤器
  13. 关于小米Ruby15.6笔记本驱动黑苹果博通蓝牙的补充
  14. 土地利用分类数据类型和下载
  15. qlearning走迷宫matlab,GitHub - MrMiilk/qlearning_robot: 用 qlearning 算法走迷宫
  16. 刚装新系统环境mscorsvw.exe进程占用CPU资料50%以上的原因
  17. Ubantu18.04环境下编译android源码
  18. layui 汉字乱码_layui table中文乱码
  19. 每日新闻:6G概念研究今年启动;德国SAP斥80亿美元收购美国Qualtrics;华为发布人工智能平台;微软收购两家游戏工作室...
  20. 导入 txt 文件数据到 MySQL 表

热门文章

  1. 桩身弹性压缩计算公式_压缩弹簧弹力的计算公式
  2. 双android手机同步工具,手机同步软件Android Manager使用图文教程
  3. 【电子知识篇】放大器定义与分类
  4. excel计算机考试,Excel计算机考试操作题全解.doc
  5. Linux 嗅探 网络扫描 攻击防御神器 NMAP
  6. C++ 逆波兰表达式
  7. QQ防撤回9.0.2 软件 源码 源文件
  8. PWM驱动MOS管H桥电路
  9. IOS 关于扬声器和听话筒的设置 ----自己试验过的,可以达到扩音器和听筒播放的效果...
  10. 手心输入法 -无广告不骚扰