130 likes | 243 Views
数据结构. (第十四讲). 绍兴文理学院. 计算机系计算机应用教研室. 数据的多对多 关系是怎样 访问 的?. 第 6 章 图 (2). 一、教学目的: 明确图的遍历的含义;掌握图的深度优先搜索遍历和广度优先搜索遍历的方法及其算法;掌握深度优先策略和和广度优先策略; 算法设计训练。. 二、教学重点: 图的遍历的含义;图的深度优先搜索遍历和广度优先搜索遍历的方法及其算法;深度优先策略和和广度优先策略; 算法设计训练。. 三、教学难点: 图的深度优先搜索遍历和广度优先搜索遍历的算法;深度优先策略和和广度优先策略; 算法设计训练。 四、教学过程:. §6.3 图的遍历.
E N D
数据结构 (第十四讲) 绍兴文理学院 计算机系计算机应用教研室
第6章 图(2) 一、教学目的:明确图的遍历的含义;掌握图的深度优先搜索遍历和广度优先搜索遍历的方法及其算法;掌握深度优先策略和和广度优先策略;算法设计训练。 二、教学重点:图的遍历的含义;图的深度优先搜索遍历和广度优先搜索遍历的方法及其算法;深度优先策略和和广度优先策略;算法设计训练。 三、教学难点:图的深度优先搜索遍历和广度优先搜索遍历的算法;深度优先策略和和广度优先策略;算法设计训练。 四、教学过程:
§6.3图的遍历 TKS 4 §6.3.0 概述 1、遍历的概念:从图中某一顶点出发访遍图中的其余顶点,使每一顶点访问且仅被访问一次。这一过程叫做图的遍历(traversing graph)。 图的遍历算法是求解图的连通性、生成树、最短路径、拓扑排序和求关键路径等算法的基础。 2、图的遍历的复杂性:回路问题:设置数组visited[0…n-1]来区分。 3、遍历的方法:深度优先搜索和广度优先搜索,对有向和无向图均适用。 §6.3.1 深度优先搜索(Depth first search) 1、深度优先搜索过程(类似于树的先序遍历) (1)从图中某个顶点v出发,访问此顶点v, 07:50
(2)找出刚访问过的顶点的第一个未被访问的邻接点,访问该顶点。以该顶点为新顶点,重复此步骤,直至刚访问过的顶点没有未被访问的邻接点为止。(2)找出刚访问过的顶点的第一个未被访问的邻接点,访问该顶点。以该顶点为新顶点,重复此步骤,直至刚访问过的顶点没有未被访问的邻接点为止。 图 G4 TKS 5 V1 V2 V3 V4 V5 V6 V7 V8 (3)返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的邻接点,访问该顶点。 (4) 重复步骤(2)和(3),直至图中所有顶点都被访问过,搜索结束。 2、示例 V1 深度优先搜索遍历得到的结点序列 V1 --> V2 V3 V2 --> V4 --> V8 --> V5 --> V3 V4 V7 V5 V6 --> V6 --> V7 V8 构成深度优先生成树 07:50
3、深度优先遍历图的算法实现 图 G4 TKS 6 V1 V2 V3 V4 V5 V6 V7 V8 (1) 非递归深度优先遍历图的算法步骤 ① 初始化 a、置所有顶点“未访问”标志; b、访问起始顶点; c、置起始顶点“已访问”标志; d、起始顶点进栈; ② 当栈非空时重复做: a、取栈顶顶点; b、若栈顶顶点存在未被访问过的邻接顶点,则选择一个顶点做: ⅰ访问该顶点; ⅱ置该顶点为“已访问”标志; ⅲ该顶点进栈; 否则,当前栈顶顶点退栈。 ③ 结束。 07:50
图 G4 TKS 7 V1 V2 V3 V4 V5 V6 V7 V8 (2) 非递归深度优先遍历图的算法描述(邻接表存储图) void dfs(algraph g,int i,int visited[]) { int stack[50],j,top;arcnode *p; for(j=0;j<g.vexnum;j++) visited[j]=0; printf("%c",g.vertices[i].data); top=0; stack[top]=i; visited[i]=1; while(top>=0) { p=g.vertices[stack[top]].firstarc; while((p!=NULL)&&visited[p->adjvex]) p=p->nextarc; if(p==NULL) top--; else { i=p->adjvex; printf(" %c",g.vertices[i].data); visited[i]=1; top++; stack[top]=i; } } } 补充算法 非递归深度 优先遍历图的算法 S14_1 07:50
a b g c d e f h k F F F F F F F F F TKS 8 (3) 遍历图 void dfstraverse(algraph g,int *visited) { for(v=0;v<g.vexnum;v++) visited[v]=0; for(v=0;v<g.vexnum;v++) if(!visited[v]) dfs(g,visited,v); } (4) 算法时间复杂度: ○(n+e) ——邻接表存储 ○(n2) ——二维数组存储 b a g c d f e h k 示例: 0 1 2 3 4 5 6 7 8 访问标志: T T T T T T T T T 访问次序: a c h d k f e b g 07:50
图 G4 TKS 9 V1 V2 V3 V4 V5 V6 V7 V8 §6.3.2 广度优先搜索(Breadth_first_search) 1、广度优先搜索遍历的过程(类似于树的按层次遍历) (1)从图中某顶点v出发,访问v; (2)依次访问v的各个未曾访问过的邻接顶点, (3)然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问; 直至图中所有已被访问的顶点的邻接点都被访问。 2、示例 V1 广度优先搜索遍历得到的结点序列 V1 --> V2 --> V3 V2 V3 --> V4 --> V5 --> V6 V4 V5 V6 V7 --> V7 --> V8 V8 构成广度优先生成树 07:50
3、广度优先搜索遍历的算法实现 图 G4 TKS 10 V1 V2 V3 V4 V5 V6 V7 V8 (1) 广度优先搜索遍历的算法步骤 ① 初始化 a、置所有顶点“未访问”标志; b、访问起始顶点; c、置起始顶点“已访问”标志; d、起始顶点入队。 ② 当队列非空时重复做 a、取队首顶点; b、对与队首顶点邻接的所有未被访问的顶点依次做: ⅰ访问该顶点; ⅱ置该顶点“已访问”标志; ⅲ 该顶点入队; c、当前队首顶点退队。 ③ 结束 07:50
图 G4 TKS 11 V1 V2 V3 V4 V5 V6 V7 V8 (2) 非递归广度优先遍历图的算法描述(邻接表存储图) void bfs(algraph g,int i,int *visited) { int queue[100],hp,tp,j; arcnode *p; for(j=0;j<g.vexnum;j++) visited[j]=0; printf("%c",g.vertices[i].data); hp=tp=0; visited[i]=1; queue[hp]=i; 07:50
while(hp<=tp) { p=g.vertices[queue[hp]].firstarc; while(p!=NULL) { i=p->adjvex; if(!visited[i]) { printf(" %c",g.vertices[i].data); visited[i]=1; tp++; queue[tp]=i; } p=p->nextarc; } hp=hp+1; } } 图 G4 TKS 12 V1 V2 V3 V4 V5 V6 V7 V8 算法6.7 非递归广度 优先遍历图的算法 S14_2 07:50
4、算法时间复杂度: TKS 13 w2 w2 ○(n+e) ——邻接表存储 ○(n2) ——二维数组存储 示例: w1 w1 V V w3 w3 w7 w7 w8 w8 五、作业: w4 w4 1、书面作业:P160:1中(6)、 (8)~(11)、(13)~(14) 2、实践:实验二、栈序列匹配 w6 w6 w5 w5 ? 07:50