图的DFS递归和非递归

看之前写的文章:html

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

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

递归:ide

参考了算法导论spa

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输出:code

v1 v3 v7 v6 v2 v5 v8 v4。htm

 

非递归要用到栈。blog

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

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

相关文章
相关标签/搜索