• 图的DFS递归和非递归


    看以前写的文章:

    图的BFS:http://www.cnblogs.com/youxin/p/3284016.html

    DFS:http://www.cnblogs.com/youxin/archive/2012/07/28/2613362.html

    递归:

    参考了算法导论

    int parent[50];
    int
    color[50];//0代表white,1 gray 2 black static int time=0; int d[50];//顶点v第一次被发现(并置v为gray色) int f[50];//结束检测v的邻接表(并置v为黑色) void DFS(Graph G,int u); void DFSTraverse(Graph G,void (*Visit)(VextexType v)) { visitFunc=Visit; for(int i=0;i<G.vexnum;i++) { color[i]=0; parent[i]=-1; } time=0; for(int i=0;i<G.vexnum;i++) { if(color[i]==0) //未访问 DFS(G,i); } } void DFS(Graph G,int u) { color[u]=1;//white vextex has just been discovered visitFunc(G.vertices[u].data); time=time+1; d[u]=time; ArcNode *p=G.vertices[u].firstarc; while(p) { int v=p->adjvex; if(color[v]==0) { parent[v]=u; DFS(G,v); } p=p->nextarc; } color[u]=2;//black,it's finished f[u]=time=time+1; }
       DFSTraverse(G,visit);
         cout<<endl;
             
         for(int i=0;i<G.vexnum;i++)
             cout<<i<<ends<<parent[i]<<endl;
         cout<<endl;
                  
         for(int i=0;i<G.vexnum;i++)
             cout<<i<<ends<<d[i]<<"----"<<f[i]<<endl;

    可以看到DFS输出:

    v1 v3 v7 v6 v2 v5 v8 v4。

    非递归要用到栈。

    void DFS2(Graph G,int u)
    {
         
        stack<int> s;
        visited[u]=true;
        s.push(u);
        
        while(!s.empty())
        {
            int v=s.top();s.pop();
             
            
            visitFunc(G.vertices[v].data);
    
            ArcNode *p=G.vertices[v].firstarc;
            while(p)
            {
                if(!visited[p->adjvex])
                {
                    s.push(p->adjvex);
                    visited[p->adjvex]=true;
                    
                }
                p=p->nextarc;
            }
            
        }
    }

    写非递归时千万要记住的是,进栈时一定要设置visited[i]=true(包括原顶点);不然有些节点会重复进栈DFS和

    二叉树的先序遍历是一样的,只不过二叉树只有2个分支,要要进右分支,在进左分支,而图只要是邻接点都进去,不分先后

    下面的代码写的比较烂:(不要用,用上面的)

    void DFS2(Graph G,int u)
    {
        color[u]=1;//white vextex has just been discovered
        visitFunc(G.vertices[u].data);
        time=time+1;
        d[u]=time;
        stack<int> s;
        ArcNode *p=G.vertices[u].firstarc;
        while(p)
        {
            color[p->adjvex]=1;
            s.push(p->adjvex);
            p=p->nextarc;
        }
        while(!s.empty())
        {
            int v=s.top();s.pop();
            //color[v]=1;//white vextex has just been discovered,这句话可以不要,因为在进栈时已经设置了
            visitFunc(G.vertices[v].data);
    
            ArcNode *p2=G.vertices[v].firstarc;
            while(p2)
            {
                if(color[p2->adjvex]==0)
                {
                    s.push(p2->adjvex);
                    color[p2->adjvex]=1;//每次进栈都要设置1
                     
                }
                p2=p2->nextarc;
            }
             
        }
    }

    这里的d[ ]和f【】不好写。

    输出:

    v1 v2 v4v8 v5 v3 v6 v7

    邻接矩阵的非递归代码:

    #include
    #include
    #define max_node 20
    #define max 20000
    using namespace std;
    
    int map[max_node][max_node];
    
    void dfs(int start,int n)
    {
        stack s;
        int i,vis[max_node],ctop;
        memset(vis,0,sizeof(vis));
        vis[start] = 1;
        printf("%d ",start);
        for (i = 1;i <= n;i++)
            if(!vis[i] && map[i][start] == 1)
            {
                vis[i] = 1;
                s.push(i);
            }
        while(!s.empty())
        {
            ctop = s.top();
            vis[ctop] = 1;
            printf("%d ",s.top());
            s.pop();
            for (i = 1;i <= n;i++)
                if(!vis[i] && map[i][ctop] == 1)
                {
                    vis[i] = 1;
                    s.push(i);
                }
        }
    }
    
    int main()
    {
        int s,t,n;
        scanf("%d",&n);
        memset(map,max,sizeof(map));
        while(1)
        {
            scanf("%d %d",&s,&t);
            if(s == 0) break;
            map[s][t] = map[t][s] = 1;
        }
        dfs(1,n);
        return 0;
    }
    输入:
    
    8
    1 2
    1 3
    2 4
    2 5
    4 8
    5 8
    3 6
    3 7
    0 0
    
    输出:
    1 3 7 6 2 5 8 4
    View Code

    图的深度优先算法的递归版本相当简洁好懂。将递归版本的算法改写成非递归版本的难度并不大,关键是要处理好如何正确的在搜索的过程中存储搜索树中的子结点,并正确的进行访问.一种实现采用了两个栈,而另一种则使用一个结点类型为队列的栈..

  • 相关阅读:
    在react中使用css module
    Hoisting(变量提升)
    JS 实现货币格式化
    使用promise封装一个retry
    【要命的神奇bug】if条件 使用 正则表达式
    iframe内媒体查询的问题
    iframe嵌套登录页-页面无法加载
    Sketch Measure切图插件无法导出标注 (换插件绕过解决)
    python项目中获取当前文件所在目录
    上传文件踩到的坑
  • 原文地址:https://www.cnblogs.com/youxin/p/3284087.html
Copyright © 2020-2023  润新知