算法导论(九)——图

来源:互联网 发布:网络上放妻协议 编辑:程序博客网 时间: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.最后如果还存在未被删除的顶点,则表示有环;否则没有环   复杂度OE+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

 

原创粉丝点击