图的深度优先搜索和广度优先搜索
2015-09-21 16:26
225 查看
深度优先搜索首先访问起始顶点v,这里假设访问只是输出结点所对应的顶点序号字段,然后,从顶点v的邻接表中选取一个未访问过的顶点w进行访问,并从w开始继续进行深度优先搜索,将v的邻接表中的当前位置保存在一个栈中,当最终搜索到一个顶点u,且u的邻接表中的顶点全部被访问过时,就从栈中取出一个顶点,并按照上述方法处理该顶点的邻接表,整个过程类似树的前序遍历。
图G的结构图和邻接表图:
其图深度搜索访问次序:v0,v1,v3,v7,v4,v5,v2,v6.
代码实现
广度优先搜索从顶点v开始,并把v标记为”已访问”,然后,访问v的邻接表中的每一个顶点,在访问过v的邻接表中的所有顶点以后,访问与v的邻接表中的第一个顶点相邻,且未访问的所有顶点,为了实现这种策略,把当前访问的顶点保存在一个队列中,在当前顶点的邻接表中的所有顶点被访问过以后,从队列中取出一个顶点,然后访问该顶点的邻接表中的所有顶点,在搜索过程中,未被访问过的顶点被访问,且存入队列,已经访问过的顶点不在被访问,当队列为空时,搜索结,类似树的层次遍历。
上面图的广度优先搜索顺序:v0,v1,v2,v3,v4,v5,v6,v7
代码实现:
上面两种算法,对图的邻接表来说,其扫描全部边的时间复杂度为O(e),而如果是图的邻接矩阵,其扫描全部边的时间复杂度为O(n2n^2).
图G的结构图和邻接表图:
其图深度搜索访问次序:v0,v1,v3,v7,v4,v5,v2,v6.
代码实现
#include <iostream> #define FALSE 0 #define TRUE 1 #include<stdio.h> //结点 typedef struct node { int value; struct node * next; }edgenode; //无向图链表的头结点 typedef struct vnode { int value;//无向图链表的头结点索引 edgenode* firstedgenode;//指向该顶点的第一个相邻结点 }topnode; //无向图指向链表链的数组 typedef topnode node_list[MAX+1]; //无向图的结构体 typedef struct linklist_graph { int nodes,edges;//无向图的结点数和边数 node_list linklist;//无向图的指向链表链的数组 }linkgraph; void dfs(int v) { edgenode* w; visited[v]=TRUE; printf("%5d",v); for(w=linkgraph.linklist[v].firstedgenode;w;w=w->next) if(!visited[w->value]) dfs(w->value); }
广度优先搜索从顶点v开始,并把v标记为”已访问”,然后,访问v的邻接表中的每一个顶点,在访问过v的邻接表中的所有顶点以后,访问与v的邻接表中的第一个顶点相邻,且未访问的所有顶点,为了实现这种策略,把当前访问的顶点保存在一个队列中,在当前顶点的邻接表中的所有顶点被访问过以后,从队列中取出一个顶点,然后访问该顶点的邻接表中的所有顶点,在搜索过程中,未被访问过的顶点被访问,且存入队列,已经访问过的顶点不在被访问,当队列为空时,搜索结,类似树的层次遍历。
上面图的广度优先搜索顺序:v0,v1,v2,v3,v4,v5,v6,v7
代码实现:
typedef struct queue *queue_pointer; //动态链式队列 typedef struct queue { int index; queue_pointer link; }; void bfs(int v) { edgenode* w; queue_pointer front,rear; front=rear=NULL; printf("%5d",v); addq(&front,&rear,v); while(front) { v=delete(&front); for(w=linkgraph.linklist[v].firstedgenode;w;w=w->next) if(!visited[w->value]) { printf("%5d",w->value); addq(&front,&rear,w->value); visited[w->value]=TRUE; } } }
上面两种算法,对图的邻接表来说,其扫描全部边的时间复杂度为O(e),而如果是图的邻接矩阵,其扫描全部边的时间复杂度为O(n2n^2).
相关文章推荐
- hdu 5464 Clarke and problem dp
- bootstrap 学习
- JVM调优总结-调优方法
- Linux下清理内存和Cache方法
- jQuery实现Tab菜单滚动切换的方法
- 第三周项目1-顺序表的基本运算(2)
- 使用ACEGI搭建权限系统
- smart_iceboy的开博声明,合并之前的qq43068902与xciceboy两个csdn的博客
- 一篇很全面的freemarker教程
- hadoop 权威指南【第三版】
- Android 解决 ScrollView嵌套ListView、GridView冲突显示不全的最快实现
- SGU 200. Cracking RSA(高斯消元+高精度)
- [转] Gradle中的buildScript代码块
- volley+NetworkImageView实现列表界面的列表项中的左侧图标展现之【实现已经加载的列表项的图标上翻的时候不重新加载】
- Struts2 Action的访问路径
- java list合并去重
- 面向对象与面向过程的区别
- 建设顺序表算法库 .
- Lucene5学习之LuceneUtils工具类简单封装
- mysql之视图