软件技术基础论文图的遍历.docx
- 文档编号:6801636
- 上传时间:2023-01-10
- 格式:DOCX
- 页数:17
- 大小:181.16KB
软件技术基础论文图的遍历.docx
《软件技术基础论文图的遍历.docx》由会员分享,可在线阅读,更多相关《软件技术基础论文图的遍历.docx(17页珍藏版)》请在冰豆网上搜索。
软件技术基础论文图的遍历
《数据结构》
课程论文报告书
题目:
图与图的遍历
系别:
机电系
学号:
学生姓名:
目录
一、基本概念
1.图的定义
2.图的基本术语
3.遍历的定义
二、图的遍历
1.深度优先遍历
C语言实现深度优先遍历
2.广度优先遍历
C语言实现广度优先遍历
三、总结
一.基本概念
1.图的定义
●图(Graph)——图G是由两个集合V(G)和E(G)组成的,记为G=(V,E)
其中:
V(G)是顶点的非空有限集
E(G)是边的有限集合,边是顶点的无序对或有序对
●有向图——有向图G是由两个集合V(G)和E(G)组成的
其中:
V(G)是顶点的非空有限集
E(G)是有向边(也称弧)的有限集合,弧是顶点的有序对,记为
●无向图——无向图G是由两个集合V(G)和E(G)组成的
其中:
V(G)是顶点的非空有限集
E(G)是边的有限集合,边是顶点的无序对,记为(v,w)或(w,v),并且(v,w)=(w,v)
2.图的基本术语
有向完全图:
n个顶点的有向图最大边数是n(n-1)。
无向完全图:
n个顶点的无向图最大边数是n(n-1)/2。
权:
与图的边或弧相关的数叫~。
网:
带权的图叫~。
子图:
如果图G(V,E)和图G‘(V’,E‘),满足
V’V,E’E
则称G‘为G的子图
邻接点:
对于无向图G(V,E),如果边(v,v’)E,则称v
和v’互为邻接点。
即:
v和v’相邻接。
依附:
边(v,v’)依附于顶点v和v’。
相关联:
边(v,v’)和顶点v和v’相关联。
顶点的度:
无向图中,顶点的度为与每个顶点相连的边数
有向图中,顶点的度分成入度与出度
入度:
以该顶点为头的弧的数目
出度:
以该顶点为尾的弧的数目
如果顶点vi的度记为TD(vi),则有n个顶点,e条边或
弧的图,满足:
路径:
路径是顶点的序列V={Vi0,Vi1,……Vin},满足
(Vij-1,Vij)E或 路径长度: 沿路径边的数目或沿路径各边权值之和 回路/环: 第一个顶点和最后一个顶点相同的路径叫~ 简单路径: 序列中顶点不重复出现的路径叫~ 简单回路/简单环: 除了第一个顶点和最后一个顶点外, 其余顶点不重复出现的回路叫~ 连通: 在无向图中,从顶点V到顶点W有一条路径,则 说V和W是连通的 连通图: 图中任意两个顶点都是连通的叫~ 连通分量: 非连通图的每一个连通部分叫~ 强连通分量: 有向图中的极大强连通子图叫~ 生成树: 一个连通图的生成树是一个极小连通子图,它含有图中的全部顶点,但只有足以构成一棵树的n-1条边 路径: 1,2,3,5,6,3 路径长度: 5 简单路径: 1,2,3,5 回路: 1,2,3,5,6,3,1 简单回路: 3,5,6,3 连通图 强连通图 非连通图 3.遍历的定义 所谓遍历(Traversal),是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。 访问结点所做的操作依赖于具体的应用问题。 遍历在二叉树、图上最重要的运算之一,是二叉树上进行其它运算之基础。 当然遍历的概念也适合于多元素集合的情况,如数组。 二.图的遍历 图的遍历: 从图中的某个顶点出发,按某种方法对图中的所有顶点访问且仅访问一次。 为了保证图中的各顶点在遍历过程中访问且仅访问一次,需要为每个顶点设一个访问标志,用以标示图中每个顶点是否被访问过,访问标志用数组visited[n]来表示。 图的遍历方法有两种: 深度优先搜索和广度优先搜索 1.深度优先遍历 ☐方法: 从图的某一顶点V0出发,访问此顶点;然后依次从V0的未被访问的邻接点出发,深度优先遍历图,直至图中所有和V0相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止 图的深度优先遍历的递归定义: 假设给定图G的初态是所有顶点均未曾访问过。 在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下: 首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。 若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。 若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。 图的深度优先遍历类似于树的前序遍历。 采用的搜索方法的特点是尽可能先对纵深方向进行搜索。 这种搜索方法称为深度优先搜索(Depth-FirstSearch)。 相应地,用此方法遍历图就很自然地称之为图的深度优先遍历。 深度优先搜索的过程 设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。 若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边。 上述过程直至从x出发的所有边都已检测过为止。 此时,若x不是源点,则回溯到在x之前被访问过的顶点;否则图中所有和源点有路径相通的顶点(即从源点可达的所有顶点)都已被访问过,若图G是连通图,则遍历过程结束,否则继续选择一个尚未被访问的顶点作为新源点,进行新的搜索过程。 深度遍历: ABCDEFGH 邻接矩阵的深度优先遍历(DFS) #include #defineMAX_VERTEX_NUM20//最大顶点数 typedefcharVertexType; typedefintEdgeType;//边上的权值 intvisited[MAX_VERTEX_NUM]={0};//访问标志 typedefstruct { VertexTypevexs[MAX_VERTEX_NUM]; EdgeTypeedges[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; intn,e;//图中当前的顶点数和边数 }AdjGraph; voidCreattMGraph(AdjGraph*G)//建立无向图的邻接矩阵 { inti,j,k,w; printf("请输入图中的顶点个数与边数: "); scanf("%d%d",&G->n,&G->e); getchar(); //建立顶点表 for(i=0;i { printf("请输入第%d个顶点: ",i+1); G->vexs[i]=getchar(); getchar(); } //邻接矩阵初始化 for(i=0;i { for(j=0;j { G->edges[i][j]=0; } } //读入e条边,建立邻接矩阵 for(k=0;k { printf("请输入边的两个顶点下标(从0开始): "); scanf("%d%d",&i,&j); //printf("请输入边的权值: "); //scanf("%d",&w); G->edges[i][j]=1; G->edges[j][i]=1; getchar(); } } voidprint(AdjGraph*G) { printf("图的邻接矩阵如下: \n"); printf("\t"); for(inti=0;i { printf("%c\t",G->vexs[i]); } printf("\n"); for(i=0;i { printf("%c\t",G->vexs[i]); for(intj=0;j { printf("%d\t",G->edges[i][j]); } printf("\n"); } } //图的深度优先搜索 voidDFSM(AdjGraph*G,inti) { intj; printf("访问结点: %c\n",G->vexs[i]); visited[i]=1; for(j=0;j { if(G->edges[i][j]==1&&visited[j]==0) { DFSM(G,j); } } } voidmain() { AdjGraphg; AdjGraph*G=&g; CreattMGraph(G); print(G); DFSM(G,0); } 2.广度优先遍历 基本思想 1、从图中某个顶点V0出发,并访问此顶点; 2、从V0出发,访问V0的各个未曾访问的邻接点W1,W2,…,Wk;然后,依次从W1,W2,…,Wk出发访问各自未被访问的邻接点; 3、重复步骤2,直到全部顶点都被访问为止。 广度优先遍历的性质 与深度优先遍历类似,广度优先遍历也有许多有用的特性: 1、广度优先生成树 在广度优先遍历中,如果将每次“前进”(纵深)路过的(将被访问的)结点和边都记录下来,就得到一个子图,该子图为以出发点为根的树,称为广度优先生成树。 这种情况与深度优先遍历类似。 类似地,也可以给广度优先生成树结点定义时间戳。 2、最短路径 显然,从v0出发广度优先遍历图,将得到v0到它的各个可达到的路径。 我们这里定义路径上的边的数目为路径长度。 与深度优先遍历不同,广度优先遍历得到的v0到各点的路径是最短路径(未考虑边权)。 C实现广度优先遍历 #include #defineMaxVerNum50 structedgenode { intendver; intinform; edgenode*edgenext; }; structvexnode { charvertex; edgenode*edgelink; }; structGraph { vexnodeadjlists[MaxVerNum]; intvexnum; intarcnum; }; //队列的定义及相关函数的实现 structQueueNode { intnData; QueueNode*next; }; structQueueList { QueueNode*front; QueueNode*rear; }; voidEnQueue(QueueList*Q,inte) { QueueNode*q=newQueueNode; q->nData=e; q->next=NULL; if(Q==NULL) return; if(Q->rear==NULL) Q->front=Q->rear=q; else { Q->rear->next=q; Q->rear=Q->rear->next; } } voidDeQueue(QueueList*Q,int*e) { if(Q==NULL) return; if(Q->front==Q->rear) { *e=Q->front->nData; Q->front=Q->rear=NULL; } else { *e=Q->front->nData; Q->front=Q->front->next; } } //创建图 voidCreatAdjList(Graph*G) { inti,j,k; edgenode*p1; edgenode*p2; cout<<"请输入顶点数和边数: "< cin>>G->vexnum>>G->arcnum; cout<<"开始输入顶点表: "< for(i=0;i { cin>>G->adjlists[i].vertex; G->adjlists[i].edgelink=NULL; } cout<<"开始输入边表信息: "< for(k=0;k { cout<<"请输入边 "; cin>>i>>j; p1=newedgenode; p1->endver=j; p1->edgenext=G->adjlists[i].edgelink; G->adjlists[i].edgelink=p1; p2=newedgenode; p2->endver=i; p2->edgenext=G->adjlists[j].edgelink; G->adjlists[j].edgelink=p2; //因为是无向图,所以有两次建立边表的过程 } } voidBFS(Graph*G,intv,intvisit[]) { QueueList*Q=newQueueList; Q->front=Q->rear=NULL; EnQueue(Q,v); while(Q->rear! =NULL) { inte=0; DeQueue(Q,&e); cout< visit[e]=1; edgenode*p=newedgenode; p=G->adjlists[e].edgelink; if(p) { intm=p->endver; if(m==0) { EnQueue(Q,m); while(visit[m]==0) { p=p->edgenext; if(p==NULL) break; m=p->endver; EnQueue(Q,m); } } } } } voidBFStraversal(Graph*G,charc) { cout<<"该图的广度优先遍历结果为: "< intvisited[MaxVerNum]; for(inti=0;i { visited[i]=0; } intm; for(i=0;i { if(G->adjlists[i].vertex==c) { m=i; BFS(G,i,visited); break; } } //继续访问未被访问的结点 for(i=0;i { if(visited[i]==0) BFS(G,i,visited); } cout< } voidmain() { Graph*G=newGraph; CreatAdjList(G); charch; cout<<"请输入开始遍历的顶点: "; cin>>ch; DFStraversal(G,ch); BFStraversal(G,ch); } 代码运行结果: 三、总结 本次试验采用的是邻接表的方式实现图的深度优先遍历和广度优先遍历。 对于深度优先遍历,主要是采用递归的方式,广度优先遍历借助队列来实现。 试验本身问题不是太大,但要注意输入的问题,什么时候用空格,什么时候用回车,这一点是需要注意的,因为一旦数据的输入有问题,结果当然也就不可能正确了。 只有正确的输入数据,建立图,才能得出正确的遍历结果。 通过对本课程的学习,我们不仅学习到了数据结构的知识,还学到了一些关于算法的知识。 数据结构中,我们还学习到了一些其他的知识,比如说二叉树、线性表等的。 学习程序类课程,我需要大大的耐心细心。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件技术 基础 论文 遍历