邻接矩阵表示图深度广度优先遍历
解释结构模型邻接矩阵
![解释结构模型邻接矩阵](https://img.taocdn.com/s3/m/6a77965254270722192e453610661ed9ad5155e6.png)
解释结构模型邻接矩阵结构模型(Structural Model)是指在软件工程中,用于描述系统的静态结构的一种模型。
它通常用于表示系统的组件、类、对象之间的静态关系以及它们的属性和行为。
结构模型可以帮助开发人员理解系统的组成部分以及它们之间的相互关系,从而更好地设计、开发和维护软件系统。
在结构模型中,最常用的表示方法是邻接矩阵(Adjacency Matrix)。
邻接矩阵是一种用来表示图形结构的矩阵。
图形结构是由节点和连接节点的边组成的。
邻接矩阵的行和列分别对应图的节点,矩阵中的元素表示节点之间是否存在边。
如果两个节点之间存在边,则对应矩阵元素的值为1;如果两个节点之间不存在边,则对应矩阵元素的值为0。
邻接矩阵可以提供关于图形结构的丰富信息。
通过分析矩阵的行和列,可以确定图中节点的数量、节点之间的连接关系、节点的度等。
邻接矩阵还可以用于进行图的遍历和算法,如深度优先(DFS)和广度优先(BFS)。
此外,邻接矩阵还可以用于解决一些图形相关的优化问题,如最短路径问题和最小生成树问题。
邻接矩阵在实际应用中有广泛的用途。
例如,在社交网络分析中,可以使用邻接矩阵来表示用户之间的关系,并通过矩阵的运算来发现社交网络中的社群结构。
在路由器和互联网中,邻接矩阵可以用来描述网络节点之间的物理连接,从而实现路由表的生成和更新。
邻接矩阵还可以用于解决诸如稀疏矩阵压缩和图形聚类等问题。
然而,邻接矩阵也存在着一些限制和不足之处。
首先,矩阵的大小由节点的数量决定,对于大型图形结构,矩阵会占用大量的内存空间。
其次,对于稀疏图,即节点之间的连接较少的情况,邻接矩阵会浪费大量的空间来表示不存在的边,从而造成存储的浪费。
此外,邻接矩阵在表示稀疏图时的运算效率较低,不适用于一些复杂的图形分析算法。
为了克服邻接矩阵的不足,还有其他的表示图形结构的方法,如邻接表(Adjacency List)和邻接多重表(Adjacency Multilist)。
数据结构第六-九章自测题及解答
![数据结构第六-九章自测题及解答](https://img.taocdn.com/s3/m/1a27a1156c175f0e7cd137ab.png)
一、概念题(每空0.5分,共45分)1.对于集合这逻辑结构来说,其中的数据元素之间也可以有各种各样的非逻辑关系,但任何一对数据元素之间没有________关系,即没有________关系。
2.查找表按其所包括的运算的不同分为________查找表和________查找表。
3.查找表中主关键字指的是________,次关键字指的是________。
4.静态查找表包括________、________、________三种基本运算。
5.动态查找表包括________、________、________、________、________五种基本运算。
6.假定key为主关键字,若顺序表中第n个元素的键值为K,则顺序查找算法的查找长度为1;若第1个元素的键值为K,则查找长度为________;若表中无键值等于K的元素,则查找长度为________。
7.二分查找在查找成功时的查找长度不超过________,其平均查找长度为________,当n较大时约等于________。
8.静态查找表的三种不同实现各有优缺点。
其中,________查找效率最低但限制最少。
________查找效率最高但限制最强。
而________查找则介于上述二者之间。
9.二叉搜索树是一种特殊的、增加了限制条件的二叉树,其限制条件是任一结点的键值________于其左孩子(及其子孙)的键值且________于其右孩子(及其子孙)的键值。
10. 在表示一棵二叉搜索树的二叉链表上,要找键值比某结点X的键值________的结点,只需通过结点X的左指针到它的左子树中去找。
11.中序遍历一棵二叉搜索树所得的结点访问序列是键值的________序列。
12.二叉搜索树上的查找长度不仅与________有关,也与二叉搜索树的________有关。
13.在随机情况下,含有n个结点的二叉搜索树的平均查找长度为________,其时间效率很高。
14.折半查找的查找效率与树的形态有关。
深度优先算法和广度优先算法的时间复杂度
![深度优先算法和广度优先算法的时间复杂度](https://img.taocdn.com/s3/m/a008581f3d1ec5da50e2524de518964bcf84d21a.png)
深度优先算法和广度优先算法都是图搜索中常见的算法,它们具有不同的特点和适用场景。
在进行全面评估之前,让我们先来了解一下深度优先算法和广度优先算法的基本概念和原理。
### 1. 深度优先算法(Depth-First Search, DFS)深度优先算法是一种用于遍历或搜索树或图的算法。
其核心思想是从起始顶点出发,沿着一条路径直到末端,然后回溯,继续搜索下一条路径,直到所有路径都被探索。
在实际应用中,深度优先算法常常通过递归或栈来实现。
### 2. 广度优先算法(Breadth-First Search, BFS)广度优先算法也是一种用于遍历或搜索树或图的算法。
其核心思想是从起始顶点出发,依次遍历该顶点的所有相邻顶点,然后再以这些相邻顶点作为起点,继续遍历它们的相邻顶点,以此类推,直到所有顶点都被遍历。
在实际应用中,广度优先算法通常通过队列来实现。
### 3. 深度优先算法和广度优先算法的时间复杂度在实际应用中,我们经常需要对算法的时间复杂度进行分析。
针对深度优先算法和广度优先算法,它们的时间复杂度并不相同。
- 深度优先算法的时间复杂度:O(V + E),其中V为顶点数,E为边数。
在最坏的情况下,如果采用邻接矩阵来表示图的话,深度优先算法的时间复杂度为O(V^2);如果采用邻接表来表示图的话,时间复杂度为O(V + E)。
- 广度优先算法的时间复杂度:O(V + E),其中V为顶点数,E为边数。
无论采用邻接矩阵还是邻接表表示图,广度优先算法的时间复杂度都是O(V + E)。
### 4. 个人理解和观点在实际应用中,我们在选择使用深度优先算法还是广度优先算法时,需要根据具体的问题场景来进行选择。
如果要寻找图中的一条路径,或者判断两个节点之间是否存在路径,通常会选择使用深度优先算法;如果要寻找最短路径或者进行层次遍历,通常会选择使用广度优先算法。
深度优先算法和广度优先算法都是非常重要的图搜索算法,它们各自适用于不同的场景,并且具有不同的时间复杂度。
图的遍历操作实验报告
![图的遍历操作实验报告](https://img.taocdn.com/s3/m/d4f076551611cc7931b765ce0508763230127443.png)
-实验三、图的遍历操作一、目的掌握有向图和无向图的概念;掌握邻接矩阵和邻接链表建立图的存储构造;掌握DFS及BFS对图的遍历操作;了解图构造在人工智能、工程等领域的广泛应用。
二、要求采用邻接矩阵和邻接链表作为图的存储构造,完成有向图和无向图的DFS 和BFS操作。
三、DFS和BFS 的根本思想深度优先搜索法DFS的根本思想:从图G中*个顶点Vo出发,首先访问Vo,然后选择一个与Vo相邻且没被访问过的顶点Vi访问,再从Vi出发选择一个与Vi相邻且没被访问过的顶点Vj访问,……依次继续。
如果当前被访问过的顶点的所有邻接顶点都已被访问,则回退到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样方法向前遍历。
直到图中所有的顶点都被访问。
广度优先算法BFS的根本思想:从图G中*个顶点Vo出发,首先访问Vo,然后访问与Vo相邻的所有未被访问过的顶点V1,V2,……,Vt;再依次访问与V1,V2,……,Vt相邻的起且未被访问过的的所有顶点。
如此继续,直到访问完图中的所有顶点。
四、例如程序1.邻接矩阵作为存储构造的程序例如#include"stdio.h"#include"stdlib.h"#define Ma*Verte*Num 100 //定义最大顶点数typedef struct{char ve*s[Ma*Verte*Num]; //顶点表int edges[Ma*Verte*Num][Ma*Verte*Num]; //邻接矩阵,可看作边表int n,e; //图中的顶点数n和边数e}MGraph; //用邻接矩阵表示的图的类型//=========建立邻接矩阵=======void CreatMGraph(MGraph *G){int i,j,k;char a;printf("Input Verte*Num(n) and EdgesNum(e): ");scanf("%d,%d",&G->n,&G->e); //输入顶点数和边数scanf("%c",&a);printf("Input Verte* string:");for(i=0;i<G->n;i++){scanf("%c",&a);G->ve*s[i]=a; //读入顶点信息,建立顶点表}for(i=0;i<G->n;i++)for(j=0;j<G->n;j++)G->edges[i][j]=0; //初始化邻接矩阵printf("Input edges,Creat Adjacency Matri*\n");for(k=0;k<G->e;k++) { //读入e条边,建立邻接矩阵 scanf("%d%d",&i,&j); //输入边〔Vi,Vj〕的顶点序号G->edges[i][j]=1;G->edges[j][i]=1; //假设为无向图,矩阵为对称矩阵;假设建立有向图,去掉该条语句}}//=========定义标志向量,为全局变量=======typedef enum{FALSE,TRUE} Boolean;Boolean visited[Ma*Verte*Num];//========DFS:深度优先遍历的递归算法======void DFSM(MGraph *G,int i){ //以Vi为出发点对邻接矩阵表示的图G进展DFS搜索,邻接矩阵是0,1矩阵 int j;printf("%c",G->ve*s[i]); //访问顶点Vivisited[i]=TRUE; //置已访问标志for(j=0;j<G->n;j++) //依次搜索Vi的邻接点if(G->edges[i][j]==1 && ! visited[j])DFSM(G,j); //〔Vi,Vj〕∈E,且Vj未访问过,故Vj为新出发点}void DFS(MGraph *G){int i;for(i=0;i<G->n;i++)visited[i]=FALSE; //标志向量初始化for(i=0;i<G->n;i++)if(!visited[i]) //Vi未访问过DFSM(G,i); //以Vi为源点开场DFS搜索}//===========BFS:广度优先遍历=======void BFS(MGraph *G,int k){ //以Vk为源点对用邻接矩阵表示的图G进展广度优先搜索 int i,j,f=0,r=0;int cq[Ma*Verte*Num]; //定义队列for(i=0;i<G->n;i++)visited[i]=FALSE; //标志向量初始化for(i=0;i<G->n;i++)cq[i]=-1; //队列初始化printf("%c",G->ve*s[k]); //访问源点Vkvisited[k]=TRUE;cq[r]=k; //Vk已访问,将其入队。
深度与广度优先搜索:迷宫问题
![深度与广度优先搜索:迷宫问题](https://img.taocdn.com/s3/m/05b6adb610661ed9ac51f31c.png)
《数据结构课程设计》报告题目:深度与广度优先搜索--迷宫问题专业计算机科学与技术学生姓名李柏班级B计算机115学号1110704512指导教师巩永旺完成日期2013年1月11日目录1简介 (1)2算法说明 (1)3测试结果 (3)4分析与探讨 (7)5小结 (9)附录 (10)附录1 源程序清单 (10)迷宫问题1 简介1、图的存储结构图的存储结构又称图的表示,其最常用的方法是邻接矩阵和邻接表。
无论采用什么存储方式,其目标总是相同的,既不仅要存储图中各个顶点的信息,同时还要存储顶点之间的所有关系。
2、图的遍历图的遍历就是从指定的某个顶点(称其为初始点)出发,按照一定的搜索方法对图中的所有顶点各做一次访问过程。
根据搜索方法不同,遍历一般分为深度优先搜索遍历和广度优先搜索遍历。
本实验中用到的是广度优先搜索遍历。
即首先访问初始点v i,并将其标记为已访问过,接着访问v i的所有未被访问过的邻接点,顺序任意,并均标记为已访问过,以此类推,直到图中所有和初始点v i有路径相通的顶点都被访问过为止。
鉴于广度优先搜索是将所有路径同时按照顺序遍历,直到遍历出迷宫出口,生成的路径为最短路径。
因此我们采用了广度优先搜索。
无论是深度优先搜索还是广度优先搜索,其本质都是将图的二维顶点结构线性化的过程,并将当前顶点相邻的未被访问的顶点作为下一个顶点。
广度优先搜索采用队列作为数据结构。
本实验的目的是设计一个程序,实现手动或者自动生成一个n×m矩阵的迷宫,寻找一条从入口点到出口点的通路。
具体实验内容如下:选择手动或者自动生成一个n×m的迷宫,将迷宫的左上角作入口,右下角作出口,设“0”为通路,“1”为墙,即无法穿越。
假设一只老鼠从起点出发,目的为右下角终点,可向“上、下、左、右、左上、左下、右上、右下”8个方向行走。
如果迷宫可以走通,则用“■”代表“1”,用“□”代表“0”,用“☆”代表行走迷宫的路径。
输出迷宫原型图、迷宫路线图以及迷宫行走路径。
数据结构:图
![数据结构:图](https://img.taocdn.com/s3/m/f867386def06eff9aef8941ea76e58fafab045aa.png)
数据结构:图在计算机科学领域,数据结构是我们组织和存储数据的方式,以便能够高效地进行操作和处理。
而图,作为一种重要的数据结构,在许多应用中都发挥着关键作用。
想象一下,我们生活中的各种关系,比如朋友关系、交通网络、电路连接等等,这些都可以用图来表示。
图由顶点(也称为节点)和边组成。
顶点代表着事物或者对象,而边则表示顶点之间的关系。
比如说,在一个社交网络中,每个人可以看作是一个顶点,如果两个人是朋友,那么在他们对应的顶点之间就会有一条边。
这种直观的表示方式让我们能够清晰地理解和分析复杂的关系。
图有两种主要的表示方式:邻接矩阵和邻接表。
邻接矩阵就像是一个表格,行和列都对应着顶点,如果两个顶点之间有边相连,对应的位置就标记为 1,否则为 0 。
这种表示方式简单直观,但当顶点数量很多而边的数量相对较少时,会浪费大量的存储空间。
邻接表则是为每个顶点创建一个链表,链表中存储着与该顶点相邻的顶点。
这种方式在处理稀疏图(边的数量相对较少的图)时,能够节省大量的空间,并且在查找相邻顶点时也比较高效。
图的遍历是操作图的重要方式之一。
深度优先遍历就像是在迷宫中一直往前走,直到走不通了再回溯;而广度优先遍历则像是以一个点为中心,一层一层地向外扩展。
深度优先遍历通常使用递归的方式实现。
从一个起始顶点开始,沿着一条路径尽可能地深入,直到无法继续,然后回溯,尝试其他的路径。
这种遍历方式在搜索、查找路径等问题中经常被使用。
广度优先遍历则使用队列来实现。
先将起始顶点入队,然后依次取出队列头部的顶点,并将其相邻的未访问过的顶点入队。
这种方式常用于计算最短路径、层次遍历等问题。
图的应用非常广泛。
在网络路由中,通过构建网络的图模型,可以找到最优的数据包传输路径;在任务调度中,可以根据任务之间的依赖关系,使用图来安排任务的执行顺序;在地图导航中,城市和道路可以表示为图,从而为用户规划最佳的出行路线。
再比如,在人工智能中的搜索算法中,图可以用来表示状态空间。
算法设计:深度优先遍历和广度优先遍历
![算法设计:深度优先遍历和广度优先遍历](https://img.taocdn.com/s3/m/67b0a31cfc4ffe473368abdb.png)
算法设计:深度优先遍历和广度优先遍历实现深度优先遍历过程1、图的遍历和树的遍历类似,图的遍历也是从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。
它是许多图的算法的基础。
深度优先遍历和广度优先遍历是最为重要的两种遍历图的方法。
它们对无向图和有向图均适用。
注意:以下假定遍历过程中访问顶点的操作是简单地输出顶点。
2、布尔向量visited[0..n-1]的设置图中任一顶点都可能和其它顶点相邻接。
在访问了某顶点之后,又可能顺着某条回路又回到了该顶点。
为了避免重复访问同一个顶点,必须记住每个已访问的顶点。
为此,可设一布尔向量visited[0..n-1],其初值为假,一旦访问了顶点Vi之后,便将visited[i]置为真。
--------------------------深度优先遍历(Depth-First Traversal)1.图的深度优先遍历的递归定义假设给定图G的初态是所有顶点均未曾访问过。
在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。
若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。
若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。
图的深度优先遍历类似于树的前序遍历。
采用的搜索方法的特点是尽可能先对纵深方向进行搜索。
这种搜索方法称为深度优先搜索(Depth-First Search)。
相应地,用此方法遍历图就很自然地称之为图的深度优先遍历。
2、深度优先搜索的过程设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。
若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边。
邻接矩阵
![邻接矩阵](https://img.taocdn.com/s3/m/7dcb5993daef5ef7ba0d3c3d.png)
哈尔滨工业大学计算机科学与技术学院实验报告课程名称:数据结构与算法课程类型:必修实验项目名称:图实验题目:图的遍历班级:0703301学号:1070330101姓名:任冬伟设计成绩报告成绩指导老师一、实验目的1)掌握图的邻接矩阵表示2)熟练掌握图的深度优先和广度优先搜索3)熟悉队列的基本操作,完成广度优先搜索二、实验要求及实验环境1)本程序是对图的邻接矩阵表示,进行广度优先和深度优先搜索2)本程序要求输入图中结点个数及边条数,以字符输入顶点信息。
然后输入边信息3)对图实现深度优先搜索4)对图实现广度优先搜索三、设计思想(本程序中的用到的所有数据类型的定义,主程序的流程图及各程序模块之间的调用关系)1.数据类型定义1)邻接矩阵struct MTGraph{char vexlist[NumbersVertices]; //顶点表int edge[NumbersVertices][NumbersVertices]; //边表int n,e; //当前顶点和边的个数};2)队列struct celltype{int element;celltype *next;};Typedef celltype *ELE;struct QUEUE {ELE front;ELE rear;};2.基本操作1)建立邻接矩阵void CreateMGragh(MTGraph &G); //建立邻接矩阵2)搜索void DFS(MTGraph G, int i); //深度优先搜索void BFS(MTGraph G, int k); //广度优先搜索3)队列的基本操作void MakeNull(QUEUE &q); //初始化bool Empty(QUEUE q); //判空char Front(QUEUE q); //返回队首void EnQueue(int x,QUEUE &q); //进队操作void Delete(QUEUE &q); //删除3.主函数流程1)创建图的邻接矩阵表示,输入图中结点个数及边条数,以字符输入顶点信息。
图的遍历数据结构实验报告
![图的遍历数据结构实验报告](https://img.taocdn.com/s3/m/17c1ed6a3d1ec5da50e2524de518964bce84d259.png)
图的遍历数据结构实验报告正文:1·引言本实验报告旨在介绍图的遍历数据结构实验的设计、实现和结果分析。
图是一种常见的数据结构,用于表示对象之间的关系。
图的遍历是指系统地访问图的每个节点或边的过程,以便获取所需的信息。
在本次实验中,我们将学习并实现图的遍历算法,并分析算法的效率和性能。
2·实验目标本实验的主要目标是实现以下几种图的遍历算法:●深度优先搜索(DFS)●广度优先搜索(BFS)●拓扑排序3·实验环境本实验使用以下环境进行开发和测试:●操作系统:Windows 10●编程语言:C++●开发工具:Visual Studio 20194·实验设计与实现4·1 图的表示我们采用邻接矩阵的方式来表示图。
邻接矩阵是一个二维数组,用于表示图中节点之间的关系。
具体实现时,我们定义了一个图类,其中包含了节点个数、边的个数和邻接矩阵等属性和方法。
4·2 深度优先搜索算法(DFS)深度优先搜索是一种经典的图遍历算法,它通过递归或栈的方式实现。
DFS的核心思想是从起始节点开始,尽可能深地访问节点,直到达到最深的节点或无法继续访问为止。
我们实现了一个递归版本的DFS算法,具体步骤如下:●从起始节点开始进行递归遍历,标记当前节点为已访问。
●访问当前节点的所有未访问过的邻接节点,对每个邻接节点递归调用DFS函数。
4·3 广度优先搜索算法(BFS)广度优先搜索是另一种常用的图遍历算法,它通过队列的方式实现。
BFS的核心思想是从起始节点开始,逐层地遍历节点,先访问离起始节点最近的节点。
我们实现了一个使用队列的BFS算法,具体步骤如下:●将起始节点放入队列,并标记为已访问。
●从队列中取出一个节点,访问该节点并将其所有未访问的邻接节点放入队列。
●重复上述步骤,直到队列为空。
4·4 拓扑排序算法拓扑排序是一种将有向无环图(DAG)的所有节点线性排序的算法。
数据结构选择题考试精选
![数据结构选择题考试精选](https://img.taocdn.com/s3/m/b0b37b363968011ca3009183.png)
一、单项选择题 (每题1分,共142分)1. 向一个有128个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动(A)个元素。
A.64B.63C.63.5D.72. 线性表是具有n个(C)的有限序列(n≠0)。
A.表元素B.字符C.数据元素D.数据项3. 下列哪种排序方法在最坏的情况下的时间复杂度是O(n*log2n)(B)。
A .直接插入排序 B. 堆排序C. 简单选择排序D. 快速排序4. 数组A[5][6]的每个元素占5个单元,将其按行优先次序存储在起始地址为1000的连续的内存单元中,则元素A[4][4]的地址为(A)。
A.1140B.1145C.1120D.11255. 从一个栈顶指针为HS的链栈中删除一个结点时,用x保存被删结点的值,则执行(D)。
A.x=HS;HS=HS->next;B.x=HS->data;C.HS=HS->next;x=HS->data;D.x=HS->data;HS=HS->next;6. 已知含6个顶点(v0,v1,v2,v3,v4,v5)的无向图的邻接矩阵如图所示,则从顶点v0出发进行深度优先遍历可能得到的顶点访问序列为(A)。
A.(v0,v1,v2,v5,v4,v3B.(v0,v1,v2,v3,v4,v5)C.(v0,v1,v5,v2,v3,v4)D.(v0,v1,v4,v5,v2,v3)7. 如下陈述中正确的是(A)。
A.串是一种特殊的线性B.串的长度必须大于零C.串中元素只能是字母D.空串就是空白串8. 在一个长度为n的顺序表中插入一个元素时,等概率情况下的平均移动元素的次数是(A)。
A.n/2B.(n-1)/2 C.n*(n-1)/2 D.(n+1)/29.数据的存储结构包括顺序、链接、散列和(D)4种基本类型。
A.向量B.数组C.集合D.索引10. 在含n个顶点和e条边的无向图的邻接矩阵中,零元素的个数为(D)。
数据结构专升本模拟题及参考答案.
![数据结构专升本模拟题及参考答案.](https://img.taocdn.com/s3/m/2b8588afd0d233d4b14e693d.png)
作业题(一)一、单项选择题1. 从逻辑上可以把数据结构分为()两大类。
A.动态结构、静态结构 B.顺序结构、链式结构C.线性结构、非线性结构 D.初等结构、构造型结构2. 链表不具有的特点是()A.插入、删除不需要移动元素 B.可随机访问任一元素C.不必事先估计存储空间 D.所需空间与线性长度成正比3.下面程序段的时间复杂度的量级为()。
For(i=1;i<=n;i++)For(j=1;j<=I;j++)For(k=1;k<=j;k++)X=x+1;A.O(1) B.O(n)C.O(n²) D.O(n³)4.在一个带头结点的双向循环链表中,若要在p所指向的结点之前插入一个新结点,则需要相继修改()个指针域的值。
A.2 B.3C.4 D.65、一个顺序存储线性表的第一个元素的存储地址是90,每个元素的长度是2,则第6个元素的存储地址是()。
A.98 B.100C.102 D.1066、判定一个栈s(最多元素为m0)为空的条件是()。
A.s-〉top! =0 B.s-〉top= =0C.s-〉top! =m0 D.s-〉top= =m07、循环队列用数组A[m](下标从0到m-1)存放其元素值,已知其头尾指针分别是front和rear,则当前队列中的元素个数是()。
A.(rear-front+m)%m B.rear-front+1C.rear-front-1 D. rear-front8、设有两个串S1与S2,求串S2在S1中首次出现位置的运算称作()。
A.连接 B.求子串C.模式匹配 D.判子串9、设串S1='ABCDEFG',S2='PQRST',函数con(x,y)返回x和y串的连接串,subs(s,i,j)返回串S的的从序号i的字符开始的j个字符组成的子串,len(s)返回串S的长度,则con(subs(S1,2,len(S2)),subs(S1,len(S2),2))的结果是()。
数据结构实验四图的深度优先与广度优先遍历
![数据结构实验四图的深度优先与广度优先遍历](https://img.taocdn.com/s3/m/375c8aa2b14e852459fb5700.png)
天津理工大学实验报告学院(系)名称:计算机与通信工程学院姓名学号专业计算机科学与技术班级2009级1班实验项目实验四图的深度优先与广度优先遍历课程名称数据结构与算法课程代码实验时间2011年5月12日第5-8节实验地点7号楼215 批改意见成绩教师签字:实验四图的深度优先与广度优先遍历实验时间:2011年5月12日,12:50 -15:50(地点:7-215)实验目的:理解图的逻辑特点;掌握理解图的两种主要存储结构(邻接矩阵和邻接表),掌握图的构造、深度优先遍历、广度优先遍历算法。
具体实验题目:(任课教师根据实验大纲自己指定)每位同学按下述要求实现相应算法:根据从键盘输入的数据创建图(图的存储结构可采用邻接矩阵或邻接表),并对图进行深度优先搜索和广度优先搜索1)问题描述:在主程序中提供下列菜单:1…图的建立2…深度优先遍历图3…广度优先遍历图0…结束2)实验要求:图的存储可采用邻接表或邻接矩阵;定义下列过程:CreateGraph(): 按从键盘的数据建立图DFSGrahp():深度优先遍历图BFSGrahp():广度优先遍历图实验报告格式及要求:按学校印刷的实验报告模版书写。
(具体要求见四)实验思路:首先,定义邻接矩阵和图的类型,定义循环队列来存储,本程序中只给出了有向图的两种遍历,定义深度优先搜索和广度优先搜索的函数,和一些必要的函数,下面的程序中会有说明,然后是函数及运行结果!#include<iostream>#include<cstdlib>using namespace std;#define MAX_VERTEX_NUM 20//最大顶点数#define MaxSize 100bool visited[MAX_VERTEX_NUM];enum GraphKind{AG,AN,DG,DN};//图的种类,无向图,无向网络,有向图,有向网络struct ArcNode{int adjvex;ArcNode * nextarc;};struct VNode{int data;ArcNode * firstarc;};struct Graph{VNode vertex[MAX_VERTEX_NUM];int vexnum,arcnum;//顶点数,弧数GraphKind kind;//图的类型};struct SeqQueue{int *base;int front,rear;SeqQueue InitQueue(){//循环队列初始化SeqQueue Q;Q.base = new int;Q.front=0;Q.rear=0;return Q;}void DeQueue(SeqQueue &Q,int &u){//出队操作u = *(Q.base+Q.front);Q.front = (Q.front+1)%MaxSize;}int QueueFull(SeqQueue Q){//判断循环队列是否满return (Q.front==(Q.rear+1)%MaxSize)?1:0;}void EnQueue(SeqQueue &Q,int x){//入队操作if(QueueFull(Q)){cout<<"队满,入队操作失败!"<<endl;exit(0);}*(Q.base+Q.rear) = x;Q.rear = (Q.rear+1)%MaxSize;void CreateDG(Graph & G,int n,int e){//初始化邻接表头结点int j;for(int i=0;i<n;++i){G.vertex[i].data=i;G.vertex[i].firstarc=NULL;}for(i=0;i<e;++i){cin>>i>>j;//输入边的信息ArcNode* s;s= new ArcNode;s->adjvex = j;s->nextarc = G.vertex[i].firstarc;G.vertex[i].firstarc = s;}}void Visit(Graph G,int u){cout<<G.vertex[u].data<<" ";}int FirstAdjVex(Graph G,int v){if(G.vertex[v].firstarc)return G.vertex[v].firstarc->adjvex;elsereturn -1;}int NextAdjVex(Graph G,int v,int w){ArcNode* p = G.vertex[v].firstarc;while(p->adjvex!=w)p = p->nextarc;if(p->nextarc)return p->nextarc->adjvex;elsereturn -1;}void DFSGrahp(Graph G,int v){visited[v]=true;Visit(G,v);//访问顶点V,对从未访问过的邻接点w递归调用DFS for(int w=FirstAdjVex(G,v);w!=0;w=NextAdjVex(G,v,w))if(!visited[w]) DFSGrahp(G,w);}void DFSTraverse(Graph G){//对图G做深度优先搜索for(int v=0;v<G.vexnum;++v)visited[v]=false;//初始化访问标志数组visitedfor(v=0;v<G.vexnum;++v)if(!visited[v]) DFSGrahp(G,v);//对尚未访问的顶点v调用DFS }void BFSGrahp(Graph G){//图的广度优先搜索SeqQueue Q;Q=InitQueue();int u;for(int v=0;v<G.vexnum;++v)if(!visited[G,v]){EnQueue(Q,v);//v入队列while(!((Q.front==Q.rear)?1:0)){DeQueue(Q,u);//对首元素出队,赋给uvisited[u]=true;Visit(G,u);for(int w=FirstAdjVex(G,u);w!=0;w=NextAdjVex(G,u,w)) //u的未访问过的邻接点w入队列if(!visited[w])EnQueue(Q,w);}}}int main(){Graph p;int n,e;cout<<"输入图的顶点及边数:"<<endl;cin>>n>>e;cout<<"创建图:"<<endl;CreateDG(p,n,e);cout<<"图的优先深度结果为:"<<endl;DFSTraverse(p);cout<<"图的广度优先结果为:"<<endl;BFSGrahp(p);printf("结果如上所示!\n");return 0;}。
图的遍历深度优先遍历和广度优先遍历
![图的遍历深度优先遍历和广度优先遍历](https://img.taocdn.com/s3/m/9c92826bcf84b9d528ea7aaf.png)
4
5
f
^
对应的邻接表
终点2作为下次的始点, 由于1点已访问过,跳过, 找到4,记标识,送输出, 4有作为新的始点重复上 述过程
1 2 4
5
输出数组 resu
3.邻接表深度优先遍历的实现
template <class TElem, class TEdgeElem>long DFS2(TGraphNodeAL<TElem, TEdgeElem> *nodes,long n,long v0, char *visited, long *resu,long &top) {//深度优先遍历用邻接表表示的图。nodes是邻接表的头数组,n 为结点个数(编号为0~n)。 //v0为遍历的起点。返回实际遍历到的结点的数目。 //visited是访问标志数组,调用本函数前,应为其分配空间并初 始化为全0(未访问) //resu为一维数组,用于存放所遍历到的结点的编号,调用本函 数前,应为其分配空间 long nNodes, i; TGraphEdgeAL<TEdgeElem> *p; nNodes=1;
1 2
4
图 20-1有向图
5
3
1 2 3 4 5
1 0 1 0 1 0
2 1 0 0 0 0
3 0 0 0 0 0
4 0 1 0 0 0
5 1 0 1 0 0
1 2 3 4 5
1 1 0 1 1
1 2 4 5
所示图的邻接矩阵g
访问标识数组 visited
输出数组 resu
例如从1点深度优先遍历,先把1设置访问标志,并置入输出数组resu,然后从邻接 矩阵的第一行,扫描各列,找到最近的邻接点2,将其设置访问标志,并进入输出数 组,接着从邻接矩阵的2行扫描,找到第一个构成边的点是1,检查访问标识数组, 发现1已经访问过,跳过,找第二个构成边 的点4,设置访问标识,进入输出数组, 再从邻接矩阵的第4行扫描,寻找构成边的点,除1外在无其他点,返回2行,继续 寻找,也无新点,返回1,找到5,将5置访问标志,进入输出数组,1行再无其他新 点,遍历结束,返回遍历元素个数为4 。
中南大学《数据结构》课程作业(在线作业)二及参考答案
![中南大学《数据结构》课程作业(在线作业)二及参考答案](https://img.taocdn.com/s3/m/5b4752f88762caaedc33d44b.png)
(一) 单选题1. 用邻接表表示图进行深度优先遍历时,通常是采用()来实现算法的。
(A) 栈(B) 队列(C) 树(D) 图参考答案: (A)2. 设图的邻接链表如图所示,则该图的边的数目是()。
(A) 4(B)5 (C) 10(D) 20参考答案: (B)3. 若采用邻接矩阵翻存储一个n 个顶点的无向图,则该邻接矩阵是一个()。
(A)上三角矩阵(B)稀疏矩阵(C)对角矩阵(D)对称矩阵参考答案: (D)4.无向图,其中:,对该图进行深度优先遍历,得到的顶点序列正确的是()。
(A)a,b,e,c,d,f (B)a,c,f,e,b,d (C)a,e,b,c,f,d(D)a,e,d,f,c,b参考答案: (D)5. 设森林F 对应的二叉树为B ,它有m 个结点,B 的根为p ,p 的右子树结点个数为n,森林F 中第一棵子树的结点个数是()。
(A)(B)(C)(D) 条件不足,无法确定参考答案: (A)6. 关键路径是事件结点网络中()。
(A) 从源点到汇点的最长路径(B) 从源点到汇点的最短路径(C) 最长回路(D) 最短回路参考答案: (A)7. 树最适合用来表示()。
(A)有序数据元素(B) 无序数据元素(C) 元素之间具有分支层次关系的数据(D) 元素之间无联系的数据参考答案:(C)8. 在一棵具有n个结点的二叉链表中,所有结点的空域个数等于()。
(A)n(B)(C)(D)参考答案:(C)9. 在一个非空二叉树的中序遍历序列中,根结点的右边()。
(A)只有右子树上的所有结点(B) 只有右子树上的部分结点(C) 只有左子树的上的部分结点(D) 只有左子树上的所有结点参考答案:(A)10. 有8个结点的无向连通图最少有()条边。
(A)5 (B) 6 (C) 7 (D) 8参考答案:(C)11. 含有10个结点的二叉树中,度为0的结点数为4,则度为2的结点数为()。
(A)3 (B) 4 (C) 5 (D) 6参考答案:(A)12. 在有n个叶子结点的哈夫曼树中,其结点总数为()。
邻接矩阵实验报告
![邻接矩阵实验报告](https://img.taocdn.com/s3/m/6862a83ccbaedd3383c4bb4cf7ec4afe05a1b112.png)
一、实验目的1. 理解邻接矩阵的概念及其在图论中的应用。
2. 掌握邻接矩阵的构建方法。
3. 学会使用邻接矩阵进行图的深度优先遍历和广度优先遍历。
4. 比较邻接矩阵和邻接表两种图的存储结构的优缺点。
二、实验内容1. 构建邻接矩阵2. 使用邻接矩阵进行图的深度优先遍历3. 使用邻接矩阵进行图的广度优先遍历4. 分析邻接矩阵和邻接表的优缺点三、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019四、实验步骤1. 构建邻接矩阵(1)定义图的顶点数量n。
(2)创建一个nn的二维数组A,用于存储邻接矩阵。
(3)根据图的边信息,将对应的A[i][j]值设置为1(表示存在边)或0(表示不存在边)。
2. 使用邻接矩阵进行图的深度优先遍历(1)初始化访问标记数组visited,用于记录顶点是否被访问过。
(2)从某个顶点v开始,将其标记为已访问,并将其加入访问序列。
(3)对于v的每个邻接顶点u,如果u未被访问过,则递归调用深度优先遍历算法,并将u加入访问序列。
(4)重复步骤3,直到所有顶点都被访问过。
3. 使用邻接矩阵进行图的广度优先遍历(1)初始化队列Q和一个访问标记数组visited。
(2)将起始顶点v入队,并将其标记为已访问。
(3)当队列不为空时,执行以下步骤:a. 从队列中取出一个顶点v。
b. 将v的邻接顶点u入队,并将u标记为已访问。
c. 将v加入访问序列。
(4)重复步骤3,直到队列空为止。
4. 分析邻接矩阵和邻接表的优缺点(1)邻接矩阵的优点:a. 查找边的时间复杂度为O(1)。
b. 遍历图的时间复杂度为O(n^2)。
c. 适用于稠密图。
(2)邻接矩阵的缺点:a. 空间复杂度为O(n^2),对于稀疏图,空间利用率低。
b. 查找边和遍历图的时间复杂度较高。
(3)邻接表的优点:a. 空间复杂度为O(n+e),对于稀疏图,空间利用率高。
b. 查找边和遍历图的时间复杂度为O(n+e)。
数据结构实验 图的邻接表和邻接矩阵操作
![数据结构实验 图的邻接表和邻接矩阵操作](https://img.taocdn.com/s3/m/e1bf9c0af78a6529647d5343.png)
p->weight=weight; p->nextarc=G.vertices[vv].firstarc; G.vertices[vv].firstarc=p; strcmp(G.vertices[vv].data,v);
q=(ArcNode *)malloc(sizeof(ArcNode)); q->adjvex=vv; q->weight=weight; q->nextarc=G.vertices[ww].firstarc; G.vertices[ww].firstarc=q; strcmp(G.vertices[ww].data,w);
实验报告 6
课程 数据结构 实验名称 图的建立及遍历
第页
专业
班级_ __ 学号_ ___ 姓名
实验日期: 2010 年 11 月 23 日
评分
一 、实验目的
1.学会用邻接矩阵和邻接表实现图结构和对图的基本操作。 2.掌握对图操作的具体实现; 3. 掌握图的两种遍历算法(深度优先、广度优先); 4、掌握求图的最小生成树和顶点间最短路径的算法;
int adjvex;//该弧指向的顶点的位置 ArcType weight; struct ArcNode *nextarc;//指向下一条弧指针 //InfoType *info;该弧相关信息的指针 }ArcNode; typedef struct VNode { VertexType data;//顶点信息 ArcNode *firstarc;//指向第一条依附该顶点的弧的指针 }VNode,AdjList[MAX_VEX_NUM]; typedef struct { AdjList vertices; int vexnum,arcnum; GraphKind kind; }ALGraph; ALGraph G; struct MiniSpanTree_Flag { VertexType adjvex; ArcType lowcost; }closedge[MAX_VEX_NUM]; typedef bool PathMatrix[MAX_VEX_NUM][MAX_VEX_NUM];
邻接矩阵表示的图的基本操作的实现
![邻接矩阵表示的图的基本操作的实现](https://img.taocdn.com/s3/m/37e7ddcf4028915f804dc2ee.png)
邻接矩阵表示的图的基本操作的实现//采用邻接矩阵完成无权无向及有向图的"建立、输出、深度遍历、广度遍历"操作#include <stdio.h>#include <stdlib.h>#define OK 1#define ERROR -1typedef int Status;typedef int ElemType; //此例中设元素为单值元素,类型为整型#define MAX_VERTEX_NUM 20 //最大顶点个数typedef int ElemType; //图顶点数据类型typedef int QueueElemType;//队列结点数据类型//链表结点类型定义typedef struct Qnode{QueueElemType data;struct Qnode *next;}QNode;//队列类型定义:typedef struct Linkqueue{QNode *front,*rear;}LinkQueue;//图的数据类型定义typedef struct Mgraph{ElemType vector[MAX_VERTEX_NUM]; //顶点向量int adj[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵int vexnum; //图中当前顶点数int arcnum; //图中当前边数} MGraph;//队列初始化Status InitLinkQueue(LinkQueue *Q){QNode *p;p=(QNode*)malloc(sizeof(QNode));//开辟头结点空间if(p!=NULL){p->next=NULL;Q->front=Q->rear=p;return OK;}elsereturn ERROR;}//链式队列的入队操作,在已知队列的队尾插入一个元素e,修改队尾指针rear。
邻接矩阵表示图-深度-广度优先遍历
![邻接矩阵表示图-深度-广度优先遍历](https://img.taocdn.com/s3/m/c4428eced4d8d15abe234e8b.png)
*问题描述:建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选两种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。
1、邻接矩阵表示法:设G=(V,E)是一个图,其中V={V1,V2,V3…,Vn}。
G的邻接矩阵是一个他有下述性质的n阶方阵:1,若(Vi,Vj)∈E 或<Vi,Vj>∈E;A[i,j]={0,反之图5-2中有向图G1和无向图G2的邻接矩阵分别为M1和M2:M1=┌0 1 0 1 ┐│ 1 0 1 0 ││ 1 0 0 1 │└0 0 0 0 ┘M2=┌0 1 1 1 ┐│ 1 0 1 0 ││ 1 1 0 1 │└ 1 0 1 0 ┘注意无向图的邻接是一个对称矩阵,例如M2。
用邻接矩阵表示法来表示一个具有n个顶点的图时,除了用邻接矩阵中的n*n个元素存储顶点间相邻关系外,往往还需要另设一个向量存储n个顶点的信息。
因此其类型定义如下:VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数和弧(边)数GraphKind kind; // 图的种类标志若图中每个顶点只含一个编号i(1≤i≤vnum),则只需一个二维数组表示图的邻接矩阵。
此时存储结构可简单说明如下:type adjmatrix=array[1..vnum,1..vnum]of adj;利用邻接矩阵很容易判定任意两个顶点之间是否有边(或弧)相联,并容易求得各个顶点的度。
对于无向图,顶点Vi的度是邻接矩阵中第i行元素之和,即n nD(Vi)=∑A[i,j](或∑A[i,j])j=1 i=1对于有向图,顶点Vi的出度OD(Vi)为邻接矩阵第i行元素之和,顶点Vi 的入度ID(Vi)为第i列元素之和。
即n nOD(Vi)=∑A[i,j],OD(Vi)=∑A[j,i])j=1j=1用邻接矩阵也可以表示带权图,只要令Wij, 若<Vi,Vj>或(Vi,Vj)A[i,j]={∞, 否则。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
*问题描述:建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选两种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。
1、邻接矩阵表示法:设G=(V,E)是一个图,其中V={V1,V2,V3…,Vn}。
G的邻接矩阵是一个他有下述性质的n阶方阵:1,若(Vi,Vj)∈E 或<Vi,Vj>∈E;A[i,j]={0,反之图5-2中有向图G1和无向图G2的邻接矩阵分别为M1和M2:M1=┌0 1 0 1 ┐│ 1 0 1 0 ││ 1 0 0 1 │└0 0 0 0 ┘M2=┌0 1 1 1 ┐│ 1 0 1 0 ││ 1 1 0 1 │└ 1 0 1 0 ┘注意无向图的邻接是一个对称矩阵,例如M2。
用邻接矩阵表示法来表示一个具有n个顶点的图时,除了用邻接矩阵中的n*n个元素存储顶点间相邻关系外,往往还需要另设一个向量存储n个顶点的信息。
因此其类型定义如下:VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数和弧(边)数GraphKind kind; // 图的种类标志若图中每个顶点只含一个编号i(1≤i≤vnum),则只需一个二维数组表示图的邻接矩阵。
此时存储结构可简单说明如下:type adjmatrix=array[1..vnum,1..vnum]of adj;利用邻接矩阵很容易判定任意两个顶点之间是否有边(或弧)相联,并容易求得各个顶点的度。
对于无向图,顶点Vi的度是邻接矩阵中第i行元素之和,即n nD(Vi)=∑A[i,j](或∑A[i,j])j=1 i=1对于有向图,顶点Vi的出度OD(Vi)为邻接矩阵第i行元素之和,顶点Vi 的入度ID(Vi)为第i列元素之和。
即n nOD(Vi)=∑A[i,j],OD(Vi)=∑A[j,i])j=1j=1用邻接矩阵也可以表示带权图,只要令Wij, 若<Vi,Vj>或(Vi,Vj)A[i,j]={∞, 否则。
其中Wij为<Vi,Vj>或(Vi,Vj)上的权值。
相应地,网的邻接矩阵表示的类型定义应作如下的修改:adj:weightype ; {weightype为权类型} 图5-6列出一个网和它的邻接矩阵。
┌∞31∞∞┐│∞∞51∞││∞∞∞∞∞││∞∞6∞∞│└∞322∞┘(a)网(b)邻接矩阵图5-6 网及其邻接矩阵对无向图或无向网络,由于其邻接矩阵是对称的,故可采用压缩存贮的方法,仅存贮下三角或上三角中的元素(但不含对角线上的元素)即可。
显然,邻接矩阵表示法的空间复杂度O(n2)。
无向网邻接矩阵的建立方法是:首先将矩阵A的每个元素都初始化成∞。
然后,读入边及权值(i,j,wij),将A的相应元素置成Wij。
2、图的遍历:*深度优先搜索深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广。
假设初始状态是图中所有的顶点未曾被访问,则深度优先遍历可从图的某个顶点V出发,访问此顶点,然后依次从V的未被访问的邻接点出发深度优先遍历图,直至图中所有和V有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中的一个未被访问的顶点,重复上述过程,直至图中所有顶点都被访问到为止。
以图7.13(a)中无向图G4为例,深度优先遍历图的过程如图7.13(b)所示。
假设从顶点V1出发进行搜索,在访问了顶点V1后,选择邻接点V2。
因为V2未曾访问,则从V2出发进行搜索。
依次类推,接着从V4,V8,V5出发进行搜索。
在访问了V5之后,由于V5的邻接点已都被访问,则搜索回到V8。
由于同样的理由,搜索继续回到V4,V2直至V1,此时由于V1的另一个邻接点为被访问,则搜索又从V 1到V3,再继续进行下去。
由此得到顶点的访问序列为:V1V2V4V8V5V3V6V7显然,这是一个递归的过程。
为了在遍历过程中便于区别顶点是否已被访问,需附设访问标志数组visted[0...n-1],其初值为0,一但某个顶点被访问,则其相应的分量置为1。
*广度优先搜索假设从图中某顶点v出发,在访问了v之后一次访问v的各个未曾访问的扩大邻接点,然后分别从这些邻接点出发依次访问他们的邻接点,并使“先被访问的邻接点”先于“后被访问的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。
若图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直到图中的顶点都被访问为止。
换句话说,广度优先遍历图的过程就是以v为起始点,有远至近,依次访问和v有路径相通且路径长度为1、2……的顶点。
例如,对图G4进行广度优先搜索遍历的过程如图7.13(3)所示,首先访问v1和v1的邻接点v2和v3,然后依次访问v2的邻接点v4和v5及v3的邻接点v6和v7,最后访问v4的邻接点v8。
由于这些顶点的邻接点均已被访问,并且图中所有顶点都被访问,由此完成了图的遍历。
得到的顶点访问序列为V1 V2V3V4V5V6V7V8和深度优先搜索类似,在遍历的过程中也需要一个访问标志数组。
并且,为了顺次访问路径长度为2、3、…的顶点,需附设队列以存储已被访问的路径长度为1、2…的顶点。
2、图的输出图的邻接矩阵是一个二维数组,运用for语句的嵌套依次输出。
主程序流程图图的构造流程图1、无向图邻接矩阵的建立算法如下:procedure build-graph; {建立无向图的邻接矩阵}beginfor i:=1 to n do read(G.vertex[i]);{读入n个顶点的信息}for i:=1 to n dofor j:=1 to e doG.arcs[i][j] =0;{将邻接矩阵的每个元素初始化成0 }for k:=1 to e do {e为边的数目}[ read(i,j,w) {读入边<i,j>和权}G.arcs[i][j]:=w]G.arcs[i][j]=G.arcs[i][i]{置对称弧}end;该算法的执行时间是O(n+n2+e),其中消耗在邻接矩阵初始化操作上的时间是O(n2),而e<n2,所以上述算法的时间复杂度是O(n2)。
2、无向网邻接矩阵的建立算法如下:procedure build-graph; {建立无向网的邻接矩阵}beginfor i:=1 to n do read(G.vertex[i]);{读入n个顶点的信息}for i:=1 to n dofor j:=1 to e doG.arcs[i][j] =maxint;{将邻接矩阵的每个元素初始化成maxint,计算机内∞用最大事数maxint表示} for k:=1 to e do {e为边的数目}[ read(i,j,w) {读入边<i,j>和权}G.arcs[i][j]:=w; G.arcs[i][j]:=w] end;该算法的执行时间是O(n+n2+e),其中消耗在邻接矩阵初始化操作上的时间是O(n2),而e<n2,所以上述算法的时间复杂度是O(n2)。
3、图的深度优先遍历算法分析beginfor i:=1 to n do(visited[i]){初始化标志数组}while (i<n){for:i=1 to n do{按要求访问邻接点}}end当用二维数组表示邻接矩阵作图的存储结构时,查找每个顶点的邻接点所需时间为O(n2),其中n为图中顶点数。
4、图的广度优先遍历算法分析beginfor i:=1 to n do(visited[i]){初始化标志数组}while (i<n){for:i=1 to n do{if…..if…..}}end二维数组表示邻接矩阵作图的存储结构,其中n为图中顶点数,查找每个顶点的邻接点所需时间为O(n2)。
#include<stdio.h>#include<malloc.h>#include<conio.h>#include<stdlib.h>#include<string.h>#define ERROR 0#define OK 1#define MAX_VERTEX_NUM 20 //定义最大值#define INFINITY 32768 //定义极大值#define MAX_INFO 20typedef int VrType; //定义新的类型typedef int InfoType;typedef char VertexType;typedef enum{DG,DN,UDG,UDN}GraphKind;//有向图,有向网,无向图,无向网typedef struct ArcCell{//邻接矩阵表示法的各个数据结构VrType adj; // 顶点关系类型。
对无权图,用或表示相邻否;对带权图,则为权值类型。
InfoType *info; // 该弧相关信息的指针} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数和弧(边)数GraphKind kind; // 图的种类标志} MGraph;typedef struct{//设置栈int elem1[MAX_VERTEX_NUM];int top;}SeqStack;int LocateVertex(MGraph G,VertexType v);void CreateUDG(MGraph &G);void CreateUDN(MGraph &G);void DepthFirstSearch1(MGraph G);void BreadthFirstSearch1(MGraph G);int CreateGraph(MGraph &G);void Display(MGraph G);/* Graph.cpp */int LocateVertex(MGraph G,VertexType v){//用于返回输弧端点所表示的数值int j=0,k;for(k=0;k<G.vexnum;++k)if(G.vertex[k]==v){j=k;break;}return(j);}void CreateUDG(MGraph &G){ // 采用数组(邻接矩阵)表示法,构造无向图int i,j,k,IncInfo;//i,j,k为计数器,IncInfo为标志符char ch; //用于吃掉多余的字符VertexType v1,v2; //用于放置输入的弧的两个顶点printf("请输入无向图G的顶点数,边数,弧是否含相关信息(是:,否:): \n"); scanf("%d,%d,%d",&G.vexnum,&G.arcnum,&IncInfo);ch=getchar(); //用于吃掉回车printf("请输入%d个顶点的值(1个字符,空格隔开):\n",G.vexnum);for(i=0;i<G.vexnum;++i) // 构造顶点向量{scanf("%c",&G.vertex[i]);ch=getchar();}printf("请输入%d条边的顶点顶点(以空格作为间隔): \n",G.arcnum);for(i=0;i<G.vexnum;++i) // 初始化邻接矩阵for(j=0;j<G.vexnum;++j){G.arcs[i][j].adj=0;G.arcs[i][j].info=NULL; // {adj,info}}for(k=0;k<G.arcnum;++k){scanf("%c %c",&v1,&v2);ch=getchar();// ch吃掉回车符i=LocateVertex(G,v1); j=LocateVertex(G,v2);if(IncInfo)scanf("%d",&G.arcs[i][j].info);G.arcs[i][j].adj=G.arcs[j][i].adj=1; // 置<v1,v2>的对称弧<v2,v1>}}//CreateUDGvoid CreateUDN(MGraph &G){ // 采用数组(邻接矩阵)表示法,构造无向网int i,j,k,w,IncInfo;//i,j,k为计数器,w用于放置权值,IncInfo为标志符char ch; //用于吃掉多余的字符VertexType v1,v2; //用于放置输入的弧的两个顶点printf("请输入无向图G的顶点数,边数,弧是否含相关信息(是:,否:):\n ");scanf("%d,%d,%d",&G.vexnum,&G.arcnum,&IncInfo);ch=getchar(); //用于吃掉回车printf("请输入%d个顶点的值(1个字符,空格隔开):\n",G.vexnum);for(i=0;i<G.vexnum;++i) // 构造顶点向量{scanf("%c",&G.vertex[i]);ch=getchar();}printf("请输入%d条边的顶点顶点(以空格作为间隔): \n",G.arcnum);for(i=0;i<G.vexnum;++i) // 初始化邻接矩阵for(j=0;j<G.vexnum;++j){G.arcs[i][j].adj=0;G.arcs[i][j].info=NULL; //{adj,info}}for(k=0;k<G.arcnum;++k){scanf("%c %c",&v1,&v2);ch=getchar();// ch吃掉回车符printf("请输入该边的权值: ");scanf("%d",&w);ch=getchar();i=LocateVertex(G,v1);j=LocateVertex(G,v2);G.arcs[i][j].adj=w;if(IncInfo)scanf("%d",&G.arcs[i][j].info);G.arcs[i][j]=G.arcs[j][i]; // 置<v1,v2>的对称弧<v2,v1>}}//CreateUDNvoid DepthFirstSearch1(MGraph G){//无向图、无向网深度优先遍历int i,j,k,visited[20],t=1,a=1; //i,j,k为计数器,visited[20]为标志符用于表示是否已经访问过SeqStack p;for(i=0;i<G.vexnum;++i) //初始化标志符visited[i]=0;visited[0]=1; //规定以第一个字符开始遍历printf("深度优先遍历开始:\n");k=0;i=0;printf("%c ",G.vertex[0]);while(i<G.vexnum){//不断以行循环在遇到符合条件时打印,每打印出一个就让t加,把合适的值用栈来表示,把指针指向新的项for(j=0;j<G.vexnum;++j){if(G.arcs[i][j].adj!=0&&G.arcs[i][j].adj!=INFINITY&&visited[j]==0){printf("%c ",G.vertex[j]);visited[j]=1;p.elem1[k]=i;p.top=k;k++;i++;a++;t++;break;}}if(j==G.vexnum){//当在某一行无法找到合适值时,输出栈内的值,返回上一行重新开始循环i=p.elem1[p.top];p.top--;k--;}if(t==G.vexnum)break; //当全部的定点都打印出来了就退出循环}printf("\n");}void BreadthFirstSearch1(MGraph G){//无向图、无向网广度优先遍历int i,j,k,visited[20],t=1; //i,j为计数器,visited[20]为标志符用于表示是否已经访问过SeqStack p;for(i=0;i<G.vexnum;++i) //初始化标志符visited[i]=0;visited[0]=1; //规定以第一个字符开始遍历printf("广度优先遍历开始:\n");k=0;i=0;printf("%c ",G.vertex[0]);while(i<G.vexnum){for(j=0;j<G.vexnum;++j)//不断以行循环在遇到符合条件时打印,每打印出一个就让t加,把指针指向新的项{if(G.arcs[i][j].adj!=0&&G.arcs[i][j].adj!=INFINITY&&visited[j]==0){printf("%c ",G.vertex[j]);visited[j]=1;p.elem1[k]=i;p.top=k;k++;t++;}}i++; //换行,重新开始循环if(t==G.vexnum)break;}printf("\n");}int CreateGraph(MGraph &G){ //构造图printf("请输入要构造的图的类型(有向图:0,有向网:1,无向图:2,无向网:3):\n");scanf ("%d",&G.kind);switch(G.kind){case 2: CreateUDG(G);break;case 3: CreateUDN(G);break;default: return ERROR;}}//CreateGraphvoid Display(MGraph G){//输出图的邻接矩阵int i,j;printf("该图的邻接矩阵为:\n");for(i=0;i<G.vexnum;++i){for(j=0;j<G.vexnum;++j){printf("%d ",G.arcs[i][j].adj);}printf("\n");}}/* main.cpp */void main(){int i;MGraph G;CreateGraph(G);DepthFirstSearch1(G);BreadthFirstSearch1(G);Display(G);scanf("%d",&i);}1、程序开始运行时输出:请输入要构造的图的类型(有向图:0,有向网:1,无向图:2,无向网:3):为了测试输入为:2显示:请输入无向图G的顶点数:输入:5显示:请输入无向图G的边数:输入:6显示:请输入无向图G的弧是否含相关信息(是:1,否:0):输入:0显示:请输入5个顶点的值(1个字符,空格隔开):输入:1 2 3 4 5显示:请输入%d条边的顶点1 顶点2(以空格作为间隔):输入:1 2 1 4 2 3 2 5 3 4 3 5显示:深度优先遍历开始:1 2 3 4 5广度优先遍历开始:1 2 4 3 5该图的邻接矩阵为:0 1 0 1 01 0 1 0 10 1 0 1 11 0 1 0 00 1 1 0 0请输入任意键退出2、程序运行结果如图:。