zoukankan      html  css  js  c++  java
  • 图的遍历递归和非递归实现

    引自:

    http://www.cnblogs.com/dolphin0520/archive/2011/07/13/2105236.html

     图的遍历有两种遍历方式:深度优先遍历(depth-first search)和广度优先遍历(breadth-first search)。

    因为深度优先需要无路可走时按照来路往回退,正好是后进先出
    广度优先则需要保证先访问顶点的未访问邻接点先访问,恰好就是先进先出

    1.深度优先遍历

       基本思想:首先从图中某个顶点v0出发,访问此顶点,然后依次从v0相邻的顶点出发深度优先遍历,直至图中所有与v0路径相通的顶点都被访问了;若此时尚有顶点未被访问,则从中选一个顶点作为起始点,重复上述过程,直到所有的顶点都被访问。可以看出深度优先遍历是一个递归的过程。

       如下图中的一个无向图

       

      其深度优先遍历得到的序列为:

      0->1->3->7->4->2->5->6

    2.广度优先遍历

       基本思想:首先,从图的某个顶点v0出发,访问了v0之后,依次访问与v0相邻的未被访问的顶点,然后分别从这些顶点出发,广度优先遍历,直至所有的顶点都被访问完。

       如上面图中

       其广度优先遍历得到的序列为:

       0->1->2->3->4->5->6->7

    #include<iostream>
    #include<queue>
    #include<stack>
    #include<stdlib.h>
    #define MAX 100
    using namespace std;
    
    typedef struct 
    {
        int edges[MAX][MAX];    //邻接矩阵
        int n;                  //顶点数
        int e;                  //边数
    }MGraph;
    
    bool visited[MAX];          //标记顶点是否被访问过
    
    void creatMGraph(MGraph &G)    //用引用作参数
    {
        int i,j;
        int s,t;                 //存储顶点编号
        int v;                   //存储边的权值
        for(i=0;i<G.n;i++)       //初始化
        {
            for(j=0;j<G.n;j++)
            {
                G.edges[i][j]=0;
            }
            visited[i]=false;
        }
        for(i=0;i<G.e;i++)      //对矩阵相邻的边赋权值
        {
            scanf("%d %d %d",&s,&t,&v);   
    //两个顶点确定一条边
    //输入边的顶点编号以及权值 G.edges[s][t]=v; } } void DFS(MGraph G,int v) //深度优先搜索 { int i; printf("%d ",v); //访问结点v visited[v]=true; for(i=0;i<G.n;i++) //访问与v相邻的未被访问过的结点 { if(G.edges[v][i]!=0&&visited[i]==false) { DFS(G,i);//若没访问则继续,而且根据顶点的序号按数序访问 } } } //stack弹出顺序有问题 void DFS1(MGraph G,int v) //非递归实现 { stack<int> s; printf("%d ",v); //访问初始结点 visited[v]=true; s.push(v); //入栈 while(!s.empty()) { int i,j; i=s.top(); //取栈顶顶点 for(j=0;j<G.n;j++) //访问与顶点i相邻的顶点 { if(G.edges[i][j]!=0&&visited[j]==false) { printf("%d ",j); //访问 visited[j]=true; s.push(j); //访问完后入栈 break; //找到一个相邻未访问的顶点,访问之后则跳出循环 } }
    //对于节点4,找完所有节点发现都已访问过或者没有临边,所以j此时=节点总数,然后把这个4给弹出来
    直到弹出1,之前的深度搜索的值都已弹出,有半部分还没有遍历,开始遍历有半部分
    if(j==G.n) //如果与i相邻的顶点都被访问过,则将顶点i出栈 s.pop(); } } void BFS(MGraph G,int v) //广度优先搜索 { queue<int> Q; //STL模板中的queue printf("%d ",v); visited[v]=true; Q.push(v); while(!Q.empty()) { int i,j; i=Q.front(); //取队首顶点 Q.pop();//弹出一个,然后遍历这个节点的子节点,然后遍历完再弹出下一个 for(j=0;j<G.n;j++) //广度遍历 { if(G.edges[i][j]!=0&&visited[j]==false) { printf("%d ",j); visited[j]=true; Q.push(j); } } } } int main(void) { int n,e; //建立的图的顶点数和边数 while(scanf("%d %d",&n,&e)==2&&n>0) { MGraph G; G.n=n; G.e=e; creatMGraph(G); DFS(G,0); printf(" "); // DFS1(G,0); // printf(" "); // BFS(G,0); // printf(" "); } return 0; }

     参考:

    http://hi.baidu.com/huifeng00/item/f06ec624935577869c63d196

    暂时没想通

    while(!s.empty())
    {int i,j;
    i=s.top();
    s.pop();
    for(j=0;j<G.n;j++)
    {
    if(g.edges[i][j]!=0&&visited[j]==false)
    {
    printf("%d",j);
    visited[j]=true;
    s.push(j);
    break;
    }
    }
    }
  • 相关阅读:
    同步机制(下)
    同步机制(上)
    处理器调度
    kubernetes源码阅读笔记——Kubelet(之二)
    Kubernetes源码阅读笔记——Controller Manager(之三)
    kubernetes源码阅读笔记——Kubelet(之一)
    kubernetes源码阅读笔记——API Server(之二)
    kubernetes源码阅读笔记——API Server(之一)
    Kubernetes源码阅读笔记——Scheduler(之二)
    Kubernetes源码阅读笔记——Scheduler(之一)
  • 原文地址:https://www.cnblogs.com/fickleness/p/3340677.html
Copyright © 2011-2022 走看看