建立一个有向图或无向图,输入其顶点数,边数,并给出相应边的权值,输出该图对应的邻接矩阵,并用递归实现其深度优先遍历和用队列实现其广度优先遍历后的结果.

图的遍历

从给定图中任意指定的顶点(称为初始点)出发,按照某种搜索方法沿着图的边访问图中所有顶点,使每个顶点仅被访问一次,这个过程称为图的遍历
图的遍历方法有两种,一种叫深度优先遍历(DFS),另一种叫广度优先遍历(BFS).

图的邻接矩阵表示

通常图的表示有两种方法:邻接矩阵,邻接表

本文用邻接矩阵实现,一是代码量更少,二是代码风格也更贴近C语言。但不论是图的哪种实现方式,其基本的实现思想是不变的。

1:节点的信息,我们用一维数组a[n]来存储,假设图共有n个节点。

2:节点与节点间的关系,我们用二维数组b[n][n]存储。

3:b[i][j]表示,从i到j有向连通,b[j][i]表示从j到i有向连通,而当i=j时(矩阵的对角线上的元素),b[i][j]没有实际意思,在遍历时,我可以用来存储定节点是否访问过。

深度优先遍历(DFS)

图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。

它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

显然,深度优先搜索是一个递归的过程

深度优先遍历特点是,选定一个出发点后进行遍历,能前进则前进,若不能前进,回退一步再前进,或再回退一步后继续前进。依此重复,直到所有与选定点相通的所有顶点都被遍历。

广度优先遍历(BFS)​​​​​​​
广度优先遍历的过程是首先访问初始点v,接着访问顶点v的所有未被访问过的邻接点v1,v2,…,vt,然后再按照v1,v2,…,vt的次序访问每一个顶点的所有未被访问过的邻接点,以此类推,直到图中所有和初始点v有路径相通的顶点都被访问过为止。
在遍历以邻接表为存储结构的图时,需要使用一个队列,

#include<stdio.h>
#include<stdlib.h>
#define MAXVEX 100   //最大定点顶点数
#define INFINITF 65535  //用 65535来表示无穷
#define MAX 100
#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Boolean;    //Boolean是布尔类型,其值是TRUE或FALSE
Boolean visited[MAX];
typedef struct{char vexs[MAXVEX];  //顶点表 int arc[MAXVEX][MAXVEX];  //邻接矩阵,可看作边表int numVertexes,numEdges;  //图中当前的顶点数 int GraphType; //图的类型
}MGraph;
typedef struct{int data[MAXSIZE];int front;     //头指针 int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;
//初始化一个空队列
int InitQueue(SqQueue *Q)
{Q->front=0;Q->rear=0;return OK;
}
int QueueEmpty(SqQueue Q)
{if(Q.rear==Q.front)return TRUE;elsereturn FALSE;
}
//循环队列入队列操作
int EnQueue(SqQueue *Q,int e)
{if ((Q->rear+1)%MAXSIZE == Q->front);  //队列满的判断return ERROR;Q->data[Q->rear]=e;  //将元素e赋值给队尾Q->rear=(Q->rear+1)%MAXSIZE; //rear指针向后移一位置,若到最后则转到数组头部return OK; }
// 循环队列出队列操作
int DeQueue(SqQueue *Q,int *e)
{if (Q->front == Q->rear)return ERROR; //队列空的判断*e = Q->data[Q->front];  //将队头元素赋值给e Q->front=(Q->front+1)%MAXSIZE; //front指针向后移一位置return OK;
}
void CreateMGraph (MGraph *G)
{int i,j,k,w;printf("输入顶点数和边数:\n");scanf("%d %d",&G->numVertexes,&G->numEdges); //输入顶点数和边数fflush(stdin);for(i=0;i<G->numVertexes;i++){printf("第%d个顶点",i+1);scanf("%c",&G->vexs[i]);getchar (); }for(i=0;i<G->numVertexes;i++)for(j=0;j<G->numVertexes;j++)G->arc[i][j]=INFINITF ; //邻接矩阵初始化 for(k=0;k<G->numEdges;k++){printf("输入边(vi,vj)上的上标i,下标j和权W:");scanf("%d %d %d",&i,&j,&w); //输入边(vi,vj)上的权WG->arc[i][j]=w;if(G->GraphType==0)G->arc[j][i]=G->arc[i][j];  //因为是无向图,矩阵对称 }
}//输出邻接矩阵
void output(MGraph *G)
{int i,j,count=0;for (i=0;i<G->numVertexes;i++)printf("\t%c",G->vexs[i]);    printf("\n");for(i=0;i<G->numVertexes;i++){printf("%4c",G->vexs[i]);for(j=0;j<G->numVertexes;j++){printf("\t%d",G->arc[i][j]);count++;if(count%G->numVertexes==0)printf("\n");}}
}
//邻接矩阵的深度优先递归算法
void DFS (MGraph G,int i)
{int j;visited[i]=TRUE;printf("%c ",G.vexs[i]);  //打印顶点for(j=0;j<G.numVertexes;j++){if(G.arc[i][j]==1&&!visited[j])DFS(G,j);  //对未访问的邻接顶点递归调用 }
}
//邻接矩阵的深度遍历操作
void DFSTraverse(MGraph G)
{int i;for(i=0;i<G.numVertexes;i++)visited[i]=FALSE;  //初始化所有顶点状态都是未访问过状态 for(i=0;i<G.numVertexes;i++)if(!visited[i])   //对未访问过的顶点调用DFS,若是连通图,只会执行一次 DFS(G,i);
}
void BFSTraverse(MGraph G)
{int i,j;SqQueue Q;for(i=0;i<G.numVertexes;i++)visited[i]=FALSE;InitQueue(&Q);  //初始化一辅助用的队列for(i=0;i<G.numVertexes;i++)  //对每个顶点做循环 {if(!visited[i])  //若是未访问过就处理 {visited[i]=TRUE;  //设置当前顶点访问过 printf("%c ",G.vexs[i]);  //打印顶点EnQueue(&Q,i);     //将此顶点入队列 while(!QueueEmpty(Q)) //若当前队列不为空 {DeQueue(&Q,&i); //将队中元素出队列,赋值给i for(j=0;j<G.numVertexes;j++){//判断其他结点若与当前顶点存在且未访问过 if(G.arc[i][j] == 1&& !visited[j]){visited[j]=TRUE;  //将找到的此顶点标记为已访问 printf("%c ",G.vexs[j]);  //打印顶点 EnQueue(&Q,j); //将找到的此顶点入队列 }}} } }
}
int main()
{MGraph G;int i,j;printf("输入图的类型(无向图0/有向图1):");scanf("%d",&G.GraphType); CreateMGraph (&G);printf("邻接矩阵数据如下:\n");output(&G); printf("\n");printf("图的深度优先遍历如下:\n");DFSTraverse(G);printf("\n图的广度优先遍历如下:\n");BFSTraverse(G);return 0;
}

图的建立(邻接矩阵)与其深度优先和广度优先遍历相关推荐

  1. 图的理解:深度优先和广度优先遍历及其 Java 实现

    遍历 图的遍历,所谓遍历,即是对结点的访问.一个图有那么多个结点,如何遍历这些结点,需要特定策略,一般有两种访问策略: 深度优先遍历 广度优先遍历 深度优先 深度优先遍历,从初始访问结点出发,我们知道 ...

  2. 邻接矩阵的深度优先和广度优先搜索

    c语言中图的邻接矩阵的深度优先和广度优先搜索 #include<stdio.h> #include<stdlib.h> typedef struct {int vexs[7]; ...

  3. c++ 数据结构 图的应用(实现图的深度优先和广度优先遍历)——以邻接表为存储结构

    数据结构实习--图及应用(图的遍历) 一.问题描述 很多涉及图上操作的算法都是以图的遍历操作为基础的.试写一个程序,演示无向图的遍历操作. 二.基本要求 以邻接表为存储结构,实现连通无向图的深度优先和 ...

  4. P202 例9-2 以如图9-8所示的带权有向图为例,编写测试上述图的深度优先和广度优先遍历函数的程序。

    P202 例9-2 以如图9-8所示的带权有向图为例,编写测试上述图的深度优先和广度优先遍历函数的程序. 头文件1:SeqList.h #include<stdio.h>#define M ...

  5. 树的基本概念和遍历规则 数据结构和算法 二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历)

    zsychanpin 博客园 首页 新随笔 联系 订阅 管理 树的基本概念和遍历规则 树的递归定义 树是n(n>0)个结点的有限集,这个集合满足下面条件:       ⑴有且仅有一个结点没有前驱 ...

  6. 【树】二叉树遍历算法(深度优先、广度优先遍历,前序、中序、后序、层次)及Java实现...

    [树]二叉树遍历算法(深度优先.广度优先遍历,前序.中序.后序.层次)及Java实现 目录 一.前序遍历 二.中序遍历 三.后序遍历 四.层次遍历 遍历的作用 二叉树是一种非常重要的数据结构,很多其它 ...

  7. 邻接矩阵,构造有向图、无向图、有向网、无向网,深度优先、广度优先遍历(C++图)

    #include <iostream> using namespace std; #define INFINITY INT_MAX #define MAX_VERTEX_NUM 20//最 ...

  8. 图的存储以及深度优先以及广度优先遍历

    转载自:http://blog.csdn.net/gamer_gyt/article/details/51498546 一:图的分类 1:无向图 即两个顶点之间没有明确的指向关系,只有一条边相连,例如 ...

  9. 图深度优先、广度优先遍历(java)

    一.图的遍历 图的遍历,即是对结点的访问.一个图有那么多个结点,如何遍历这些结点,需要特定策略,一般有两种访问策略:(1)深度优先遍历(2)广度优先遍历深度优先遍历基本思想. 二.深度优先遍历 图的深 ...

最新文章

  1. 图解Hbase--大数据平台技术栈07
  2. 最详细的JavaWeb开发基础之java环境搭建(Windows版)
  3. 腾讯优图×厦大再破三项医疗AI世界纪录,提升胸部多器官分割准确度
  4. Android 开发学习随笔
  5. 可恶的.NET FRAME,将一切变得更简单,还是更复杂?
  6. HTML5中本地数据库(SQLLite)的基础
  7. 轻松学会多线程(四)——synchronized同步keyword知多少
  8. Spring(10)——bean作用范围(二)—自定义scope
  9. 仿分词统计的MapReduce 程序。
  10. android手机通讯录格式转换,手机通讯录csv格式转vcf格式工具 安卓电话本数据格式转换程序...
  11. 急需能临时发邮件的临时邮箱 临时邮箱怎么注册 邮箱163注册入口在哪
  12. java编程符号大全_数学符号大全
  13. ⚡【图像描述】pytorch_image_caption
  14. css外边距溢出处理方法,CSS高度坍塌和外边距溢出问题及解决方法
  15. 相机的内外参与相机标定
  16. 电脑编程技巧与维护杂志社供稿一篇
  17. C#20位纯数字条形码制作
  18. Android热修复学习之旅——HotFix完全解析
  19. 注册表恢复被篡改的默认浏览器
  20. window10 自带浏览器ie11无法启动 问题解决

热门文章

  1. DEJA_VU3D - Cesium功能集 之 001-填挖方分析
  2. 计算机学院第三周语法组及算法组作业
  3. 考研计算机专业复试英语问答,考研复试:英语口语常问的16个问题 附回答模板...
  4. [DP之家]一个初学者想要的面试宝典
  5. 小程序代码上传-审核-发布,体验者权限设置
  6. SSM商家进销存网站系统
  7. 免费开源证券数据平台
  8. uni-app使用i18n实现多语言的切换及国际化开发
  9. 如何避免把路走窄?程序员须记住:解决问题比写代码更重要!
  10. EXCEL中一列(行)转多行多列或多行多列转一列(行)