算法导论(九)——图
来源:互联网 发布:网络上放妻协议 编辑:程序博客网 时间:2024/06/05 23:45
算法导论(九)——图
广度优先搜索(Breadth First Search):从一个顶点开始,搜索所有可到达的顶点。它将邻接未访问点都加入队列,在对当前访问点进行邻接搜索。
【类似二叉树的层次遍历】
virtual void bfs(int v,int reach[],intlabel) {
arrayQueue<int>q(10);
q.push(v);
reach[v]= label;//from v
while(!q.empty()) {
//deletewhich had been labeled
intw = q.front();
q.pop();
//adjacentvertex
vertexIterator<T>*iw = iterator(w);
intu;
while((u=iw->next())!=0){
if(reach[u] == 0) {
q.push(u);
reach[u]= label;
}
}
deleteiw;
}
}
在实际操作时,针对邻接加权有向图 (a[w][u])或链接图(u=aList[w].firstNode,u=u->next),采用定制版的代码能提高效率,主要改动是搜索邻接w的未访问的顶点部分。参考P409.
深度优先搜索(Depth First Search):它将邻接未访问点当作候选,从某个点开始搜索,终止时返回上一级搜索。
【类似二叉树的前序遍历】
void dfs(int v, int reach[], int label) {
graph<T>::reach= reach;
graph<T>::label= label;
rDfs(v);
}
void rDfs(int v){
reach[v]= label;
vetexIterator<T>*iv = iterator(v);
intu;
while((u = iv->next) != 0) {
rDfs(u);
}
deleteiv;
}
详细代码见:http://blog.chinaunix.net/uid-26548237-id-3483650.html
比较:两种方法具有相同的时间和空间复杂性,不过它们的最好和最坏情况恰好相对。深度优先搜索效率更高用得更多。
最短路径算法,
1. 单源路径——Dijkstra Alg
【最短路径的子路径也是最短路径】
面试常见问题:
1. 判断图是否存在环G=(V,E)
无向图:
① i)如果E>=V,则根据图论知识可直接判断存在环路。(证明:如果没有环路,则该图必然是k棵树 k>=1。根据树的性质,E=V-k)
ii)如果E<V,
1.求出图中所有顶点的度,
2.删除图中所有度<=1的顶点以及与该顶点相关的边,把与这些边相关的顶点的度减一
3.如果还有度<=1的顶点重复步骤2
4.最后如果还存在未被删除的顶点,则表示有环;否则没有环 复杂度O(E+V),
注:初始时刻统计所有顶点的度的时候,复杂度为(V + E),最差的复杂度就为O(EV)了。
②遍历整图,找到连通域P个,若 E + P > V,则原图有环,否则无环
③ DFS搜索图,在遍历的过程中,发现某个节点有一条边指向已经访问过的节点,并且这个已访问过的节点不是当前节点的父节点,则表示存在环。该算法的复杂度为O(V)。
为防止环重复计算,将节点分为白、灰、黑三种状态。
【http://blog.csdn.net/u010040029/article/details/52861473】
有向图:
①拓扑排序,若不能完成则含有环
计算图中所有点的入度,把入度为0的点加入栈;如果栈非空:( 取出栈顶顶点a,输出该顶点值,删除该顶点,从图中删除所有以a为起始点的边,如果删除的边的另一个顶点入度为0,则把它入栈);如果图中还存在顶点,则表示图中存在环;否则输出的顶点就是一个拓扑排序序列
②强连通域(对于一个图的某个子图,该子图中的任意u->v,必有v->u)
③改进的DFS。将深搜的点加一个特殊标记,如果从当前的点往下搜的时候,发现了这个特殊标记,立刻判定有环。【http://blog.csdn.net/panhe1992/article/details/8366466】
或者是每个节点标记成白、灰、黑三种状态,按照节点标记为黑色的时间,越先标记为黑色,在拓扑序列中越靠后(栈) 【http://blog.csdn.net/u010040029/article/details/52861473】
- 算法导论(九)——图
- 《算法导论》学习心得(九)——栈(JAVA)
- 算法导论(九)kmp匹配算法
- 算法导论学习笔记(九):红黑树
- 算法导论—二分图
- 算法导论(六)——图算法
- 算法导论—堆
- 算法导论—队列
- 算法导论—哈希
- 算法导论—红黑树
- 算法导论—KMP
- 算法导论—贪心算法
- 结构算法导论——图
- 算法导论(一)——基础知识
- 算法导论(三)——数据结构
- 算法导论——(3)红黑树
- 算法导论(五)——树
- 算法导论九大排序总结
- MySQL数据库学习10-查询数据:合并查询结果、取别名
- Android RGB与int型颜色互转
- Less中的命名空间
- 一个线程执行多个任务,要按照顺序执行
- 2017.11.15 c语言基础与提高(三)
- 算法导论(九)——图
- 《计算机网络》概述
- 冒泡排序的解读
- 机器学习理论篇之激活函数优劣比较
- (十一)、Java复习笔记之多线程(2)
- BootStrap + AngularJS 实现自定义分页
- Ajax提交与传统表单提交的区别说明
- 八数码广搜代码
- Hbase API使用(一)