数据结构第7章 图_void dfs(algraph g, int v)实现了从顶点v开始对图g进行深度优先搜索,为何还_^鸢飞鱼跃^的博客-程序员宅基地

技术标签: dfs  算法  图计算  c语言  数据结构  

图的定义和术语

G r a p h = ( V , E ) Graph=(V,E) Graph=(V,E)
V:顶点(数据元素)的有穷非空集合;
E:边的有穷集合。
在图G中,如果代表边的顶点对是无序的,则称G为无向图。用圆括号序偶表示无向边。如果表示边的顶点对是有序的,则称G为有向图。用尖括号序偶表示有向边。

在这里插入图片描述

端点和邻接点
无向图:若存在一条边(i,j),则顶点i和顶点j为端点,它们互为邻接点。
有向图:若存在一条边<i,j>,则顶点i为起始端点(简称为起点),顶点j为终止端点(简称终点),它们互为邻接点。
关联(依附)
存在 ( v i , v j ) / < v i , v j > (v_i, v_j)/ <v_i, v_j> (vi,vj)/<vi,vj>, 则称该边/弧关联于顶点 v i v_i vi v j v_j vj
顶点v的度TD(v)入度ID(v)出度OD(v)
无向图:以顶点 i 为端点的边数称为该顶点的度。
有向图:以顶点i为终点的入边的数目,称为该顶点的入度。以顶点i为始点的出边的数目,称为该顶点的出度。一个顶点的入度与出度的和为该顶点的度。
完全图
无向图:每两个顶点之间都存在着一条边,称为完全无向图, 包含有n(n-1)/2条边。
有向图:每两个顶点之间都存在着方向相反的两条边,称为完全有向图,包含有n(n-1)条边。
子图
设有两个图G=(V,E)和G’=(V’,E’),若V’是V的子集,且E’是E的子集,则称G’是G的子图。

路径长度是指一条路径上经过的边的数目。
若一条路径上除开始点和结束点可以相同外,其余顶点均不相同,则称此路径为简单路径
若一条路径上的开始点与结束点为同一个顶点,则此路径被称为回路或环。开始点与结束点相同的简单路径被称为简单回路或简单环

连通、连通图和连通分量(无向图)
连通:若从顶点i到顶点j有路径,则称顶点i和j是连通的。
连通图:若图中任意两个顶点都连通,则称为连通图,否则称为非连通图。
连通分量:无向图G中的极大连通子图称为G的连通分量。
极大连通子图:该子图是 G 连通子图,将G 的任何不在该子图中的顶点加入,子图不再连通。
强连通图和强连通分量(有向图)
连通:若从顶点i到顶点j有路径,则称从顶点i到j是连通的。
强连通图:若图G中的任意两个顶点i和j都连通,即从顶点i到j和从顶点j到i都存在路径,则称图G是强连通图。

图的存储结构

邻接矩阵表示法

设G=(V,E)是具有n(n>0)个顶点的图,顶点的编号依次为0~n-1。
G的邻接矩阵A是n阶方阵,定义为:
A [ i ] [ j ] = { 1 ,  如果  < i , j > ∈ E  或者  ( i , j ) ∈ E 0 ,  否则  A [i][j]=\left\{\begin{array}{ll}1, & \text { 如果 }<i, j>\in E \text { 或者 }(i, j) \in E \\ 0, & \text { 否则 }\end{array}\right. A[i][j]={ 1,0, 如果 <i,j>E 或者 (i,j)E 否则 
分析1:无向图的邻接矩阵是对称的;
分析2:顶点i 的度=第 i 行 (列) 中1 的个数;
特别:完全图的邻接矩阵中,对角元素为0,其余1。

有向图的邻接矩阵
第i行含义:以结点vi为尾的弧(即顶点i的出边);
第i列含义:以结点vi为头的弧(即顶点i的入边)。
分析1:有向图的邻接矩阵不一定是对称的。
分析2:顶点i的出度 = 第i行元素之和
顶点i的入度 = 第i列元素之和
顶点i的度 = 第i行元素之和+第i列元素之和

邻接表表示法

对图中每个顶点i建立一个单链表,将顶点i的所有邻接点链起来。有向图的邻接表可以只存出边或只存入边。

邻接矩阵与邻接表表示法的关系

  1. 联系:邻接表中每个链表对应于邻接矩阵中的一行,链表中结点个数等于一行中非零元素的个数。
  2. 区别
    ① 对于任一确定的无向图,邻接矩阵是唯一的(行列号与顶点编号一致),但邻接表不唯一(链接次序与顶点编号无关)。
    ② 邻接矩阵的空间复杂度为O(n2),而邻接表的空间复杂度为O(n+e)。
  3. 用途:邻接矩阵多用于稠密图;而邻接表多用于稀疏图

图的遍历

深度优先搜索( DFS ——Depth First Search)

深度优先遍历过程:

  1. 从图中某个初始顶点v出发,首先访问初始顶点v。
  2. 依次从所有与顶点v相邻且没被访问过的顶点w出发进行深度优先搜索。

基于邻接矩阵的DFS算法

void DFS(MGraph G, int v)
{
          // 以顶点v为起点深度优先遍历图G,图G采用邻接矩阵存储 
  cout<<v;  visited[v] = 1;  		//访问第v个顶点
  for(int w = 0; w< G.vexnum; w++)  //依次检查邻接矩阵v所在的行  
        if((G.arcs[v][w]!=0) && (!visited[w])) //w是v的邻接点,如果w未访问,则递归调用DFS 
            DFS(G, w);       
} 

基于邻接表的DFS算法的实现

void DFS(ALGraph G, int v)
{
        //以顶点v为起点深度优先遍历图G,图G为邻接表类型 
    cout<<v;  visited[v] = 1;          //访问第v个顶点
    ArcNode *p= G.adjlist[v].firstarc; //p指向v的边链表的第一个边结点 
    while(p!=NULL) //边结点非空 
    {
         
        w=p->adjvex;               	      //表示w是v的邻接点 
        if(!visited[w])  
            DFS(G, w); 	     //如果w未访问,则递归调用DFS 
        p=p->nextarc;                 //p指向下一个边结点 
    } 
} 

用邻接矩阵来表示图,遍历图中每一个顶点都要从头扫描该顶点所在行,时间复杂度为 O ( n 2 ) O(n^2) O(n2)
用邻接表来表示图,虽然有 2e 个表结点,但只需扫描 e 个结点即可完成遍历,加上访问 n个头结点的时间,时间复杂度为O(n+e)。

广度优先搜索( BFS——Breadth First Search)

广度优先遍历的过程:

  1. 访问初始点v,v入队;
  2. 出队一个节点记为w,访问w的每个临节点p,将p入队;
  3. 若队列为空,退出,否则返回步骤2;

基于邻接表的BFS算法的实现

void BFS(ALGraph G,int v)
{
            
    int w, i;
    ArcNode *p;
    SqQueue *qu;		//定义环形队列指针
    InitQueue(qu);		//初始化队列
    int visited[MAXV];            	//定义顶点访问标记数组
    for (i=0;i<G.vexnum;i++) 
        visited[i]=0;	  	//访问标记数组初始化
    printf("%2d",v); 		//输出被访问顶点的编号
    visited[v]=1;              	//置已访问标记
    enQueue(qu,v);
    while (!QueueEmpty(qu))       	//队不空循环
    {
    	deQueue(qu,w);		//出队一个顶点w
        p=G.adjlist[w].firstarc; 	//指向w的第一个邻接点
        while (p!=NULL)		//查找w的所有邻接点
        {
       if (visited[p->adjvex]==0) 	//若当前邻接点未被访问
            {
    	printf("%2d",p->adjvex);  //访问该邻接点
                visited[p->adjvex]=1;	//置已访问标记
                enQueue(qu,p->adjvex);	//该顶点进队
            }
            p=p->nextarc;              	//找下一个邻接点
        }
    }
    printf("\n");
}

有向无环图及其应用

最短路径

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44563671/article/details/112210309

智能推荐

软件工程习题200题之二 _软件的缺陷为什么在软件开发和维护过程中会扩大?-程序员宅基地

我的软件工程笔记99年末的一段,是当时几乎所有软件工程书籍的习题。这里整理出来,希望对大家学习软件工程有益。 1、 Statemate方法是如何解决实时设计的特殊问题的? 2、 什么是规格说明语言?它具有什么性质? 3、 什么是设计语言?它具有什么性质? 4、 CASE环境语言提出了什么要求?如何实现? 5、 什么是原型开发语言?它具有什么性质? _软件的缺陷为什么在软件开发和维护过程中会扩大?

QT5利用openCV调试高清摄像头_qt 摄像头的曝光参数 范围-程序员宅基地

//#include "mainwindow.h"//#include <QApplication>//int main(int argc, char *argv[])//{// QApplication a(argc, argv);// MainWindow w;// w.show();// return a.exec();//}#i..._qt 摄像头的曝光参数 范围

数据库八股文自述_小白大菜的博客-程序员宅基地

1.MySQL索引有哪些数据结构?答:B+tree,以及Hash。Hash索引比较适合单值的查找,但不适合范围查询,Hash索引的单值查找时间复杂度为O(1).B+tree查找的时间复杂度为O(logn),但是B+适合范围查询以及扫表。Innode和MyISAM是不支持hash索引的。2.MySQL索引结构为什么不用B,而用B+?答:B树是每个节点都会存放数据,而B+的数据只会存放在叶子节点的链表上,且该链表是个双向链表,因此B+相对于B来说,最大的优势就是适合扫表。具体原因为,因为B每个节点都存放数

【C语言】找出3个数当中的最大值,并输出最大值_找出三个参数中最大的那个并返回-程序员宅基地

【C语言】找出3个数当中的最大值,并输出最大值一、实现原理:二、整体源码:一、实现原理:1、首先要定义一个主函数main()函数,因为主函数是程序的入口,没有入口,程序便无法正常运行。一般我们开始写程序的时候,都要先引入头文件和编写主函数,具体代码格式如下:#include<stdio.h>int main() { return 0;}Note:此处的主函数主要用来获取值和输出值,具体的算法在maxvalue()中实现2、其次就是定义一个maxvalue()函数,用于判断三_找出三个参数中最大的那个并返回

vSphere ESXI 7.0镜像 Rufus U盘安装盘制作(Windows)_vmware_esxi_7.0.0镜像写入工具-程序员宅基地

VMware ESXI又叫做(VMware vSphere Hypervisor),vSphere Hypervisor 是一个“裸机” 可以提供动态的硬体资源配置及弹性设定的虚拟化管理程序。可直接安装在一般的服务器并且同时间内运作多个虚拟机,并将vSphere上的资源共享,ESXi在安装设定虚拟机方面,仅需几分钟的时间就能设定完成,支持整合应用,可节省管理 IT 基础架构所用的时间和成本。一、下载制作U盘启动的工具Rufus点击此处官网下载Rufus二、Rufus安装完成后启动1、点击_vmware_esxi_7.0.0镜像写入工具

c语言版本的coroutine-程序员宅基地

#include <stdio.h>int function(void) { static int i, state = 0; switch (state) { case 0: goto LABEL0; case 1: goto LABEL1; } LABEL0: /* start of ..._c语言种coroutine_fn

随便推点

IOS项目之UICollectionView中Item布局偏移问题_uicollectionview 偏移-程序员宅基地

在使用UICollectionView做九宫格布局的时候,或多或少都会出现一些不尽人意的问题。图片是从网络上找来的,我自己懒得截图了,文章内容确是我自己写的。请不要有争议。看两个图,大家就很容易看出问题所在,这个是水平滑动后的问题,其实垂直滑动也是有这个问题的。大家看了水平滑动问题解决方案之后,就可以很好地解决垂直滑动的同样问题。首先我们可以确定UICollection_uicollectionview 偏移

用C语言实现3个数的排序-程序员宅基地

test.c#include &lt;stdio.h&gt;int main(){ int a = 1; int b = 2; int c = 2; if ((a &gt; b) &amp;&amp; (a &gt; c)) { printf("%d\n", a); } else if (b &gt; c) { printf("%d\n", b); } else ...

基于mujoco环境下的ant_v2 ppo算法训练_mujoco施加算法-程序员宅基地

import gymimport torchimport numpy as npimport argparseimport matplotlib.pyplot as pltimport torch.nn as nnimport torch.optim as optimfrom collections import dequeimport syssys.argv = ['run.py']parser = argparse.ArgumentParser()parser.add_arg._mujoco施加算法

阿里巴巴图表库 Bizcharts 正式开源-程序员宅基地

写在前面 阿里巴巴于去年开放了它的内部图表库 Bizcharts 初版,在这一年的时间里,Bizcharts 新增了许多特性,并对渲染细节及渲染性能进行大幅度的调优。 本文将简单的介绍阿里开源图表库 Bizcharts,主要分为以下几个方面: 它的由来 适合什么业务场景..._阿里图标库是开源的吗

【KVM系列03】KVM的I/O 全虚拟化和准虚拟化-程序员宅基地

第三章 I/O 全虚拟化和准虚拟化 1. 全虚拟化 I/O 设备1.1 原理1.2 QEMU 模拟网卡的实现1.3 RedHat Linux 6 中提供的模拟设备1.4 qemu-kvm 关于磁盘设备和网络...

android自定义Dialog实现文件下载和下载进度-程序员宅基地

最近要实现一个检验更新的功能,当进入程序的时候,开始请求服务器,然后得到服务器的响应更新结果!如果需要更新的话,就打开一个Dialog,在Dialog上面下载文件,于是自己研究了一个自定义dialog的实现,也完成了在dialog上面有进度的下载文件(自己的作图技术查,随便画了一个背景),效果图如下: ...

推荐文章

热门文章

相关标签