• Non recursive Depth first search


    深度优先非递归实现算法:

    1 递归算法:

    //初始化相关数据结构
    DFS(G)
    -----------------------------------------------------------------------------------
    1  for each vertex u ∈ G.V
    2      u.color ← WHITE       // paint all vertices white; undiscovered
    3      u.π ← NIL
    4      time ← 0              // global variable, timestamps
    5  for each vertex u ∈ G.V
    6      if u.color = WHITE
    7          DFS-VISIT(G,u)
    
    DFS-VISIT(G, u)
    -----------------------------------------------------------------------------------
    1  u.color ← GRAY          // grey u; it is discovered
    2  time ← time + 1 
    3  u.d ← time
    4  for each v ∈ G.Adj[u]   // explore edge (u,v)
    5      if v.color == WHITE
    6          v.π ← u
    7          DFS-VISIT(G,v) 
    8  u.color ← BLACK         // blacken u; it is finished
    9  time ← time + 1
    10 u.f ← time


    #ifndef GCC_LINUX_
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    #endif
    #include "Graph.h"
    
    enum color{WHITE, GRAY, BLACK};
    int colour[MAX_VERTEX_NUM];
    int time[MAX_VERTEX_NUM];
    int curTime;
    
    void DFSRec(LGraph graph, int u){
        cout<<"for debug"<<endl;
        cout<<"u: "<<u<<endl;
        colour[u] = GRAY;
        time[u] = ++curTime;
        //DFS adj node
        adjnode *temp;
        temp = graph.vertices[u].firstadj;
    
        while(temp){
            int v = temp->index;
            //for debug
            cout<<"for debug"<<endl;
            cout<<"v: "<<v<<" line: "<<__LINE__<<endl;
            if(colour[v] == WHITE)
                DFSRec(graph, v);
            else if(colour[v] == GRAY)
                cout<<"back edge between "<<u<<" and "<<v<<endl;
            else
                cout<<"cross edge between "<<u<<" and "<<v<<endl;
            temp = temp->adjnext;
        }
        colour[u] = BLACK;
    }
    
    void DFSTraverse(LGraph graph){
        for(int k = 1; k < graph.vexnum + 1; k++){
            if(colour[k] == WHITE) DFSRec(graph, k);
            cout<<__LINE__<<" for debug: "<<k<<endl;
        }
    }
    
    int main()
    {
        LGraph* graph;
        graph = CreateGraph(graph);
        cout<<graph->edgenum<<endl;
        cout<<graph->vexnum<<endl;
        print(*graph);
        DFSTraverse(*graph);
        //print time visit
        cout<<"print the visit array:"<<endl;
        for(int i = 1; i < graph->vexnum + 1; i++)
            cout<<time[i]<<" ";
        cout<<endl;
    
        int ch;
        cout<<"enter integer for terminating:"<<endl;
        cin>>ch;
        return 0;
    }
    


    2 非递归算法

    1   for each vertex u ∈ G.V //initialize colour array and time
    2       u.color ← WHITE
    3       u.π ← NIL
    4   time = 0
    5   for each vertex u ∈ G.V
    6       if u.color = WHITE
    7           u.color ← GRAY
    8           time ← time + 1
    9           u.d ← time
    7           push(u, S)
    8           while stack S not empty
    9               u ← pop(S)
    10              for each vertex v ∈ G.Adj[u]
    11                  if v.color = WHITE
    12                      v.color = GRAY
    13                      time ← time + 1
    14                      v.d ← time
    15                      v.π ← u
    16                      push(v, S)
    17              u.color ← BLACK 
    18              time ← time + 1
    19              u.f ← time
    具体实现代码如下:
    栈采用数组实现:
    #ifndef GCC_LINUX_
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    #endif
    #include "Graph.h"
    
    int myStack[MAX_VERTEX_NUM];
    int top = 0; //we not use array[0]
    bool visited[MAX_VERTEX_NUM];
    int timeSec[MAX_VERTEX_NUM];
    int curTimeSec;
    
    void DFSNoRecur(LGraph graph, int u){
        cout<<u;
        myStack[top++] = u;
        cout<<" top:"<<top<<endl;
        adjnode* temp;
        //for test
        int test = 1;
        while(top){
            int v = myStack[top - 1];
            cout<<test++<<" for test top: "<<top;
            cout<<" stack elem: "<<v<<endl;
            visited[v] = true;
            timeSec[v] = ++curTimeSec;
            temp = graph.vertices[v].firstadj;
            cout<<"pointer temp: "<<temp<<endl;
            top--; //Pop
        cout<<top;
            while(temp != NULL){
               if(visited[temp->index] == false){
                 myStack[top++] = temp->index;
                 cout<<test++<<" for test top: "<<top;
                 cout<<" stack elem: "<<myStack[top - 1]<<endl;
               }
               else{
                 cout<<"back edge between "<<temp->index;
                 cout<<" and "<<v<<endl;
               }
            temp = temp->adjnext;
            }//while
        }//while(top)
    }
    
    void DFSTravNRecur(LGraph graph){
        cout<<"No recursive DFS starting"<<endl;
        for(int v = 1; v < graph.vexnum + 1; v++)
            if(visited[v] == false) DFSNoRecur(graph, v);
        cout<<"No recursive DFS terminating"<<endl;
    }
    
    int main()
    {
        LGraph* graph;
        graph = CreateGraph(graph);
        cout<<graph->edgenum<<endl;
        cout<<graph->vexnum<<endl;
        print(*graph);
        DFSTraverse(*graph);
        //print time visit
        cout<<"print the time array:"<<endl;
        for(int i = 1; i < graph->vexnum + 1; i++)
            cout<<time[i]<<" ";
        cout<<endl;
    
        DFSTravNRecur(*graph);
        cout<<"print the visit array:"<<endl;
        for(int i = 1; i < graph->vexnum + 1; i++)
            cout<<time[i]<<" ";
        cout<<endl;
    
        int ch;
        cout<<"enter integer for terminating:"<<endl;
        cin>>ch;
        return 0;
    }
    


    "Graph.h"文件代码定义:

    #ifndef GCC_LINUX_
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    #endif
    #define MAX_VERTEX_NUM 128
    
    struct adjnode{
        int index;
        struct adjnode* adjnext;
    };
    
    typedef struct vexnode{
        struct adjnode* firstadj;
    }VertexLink[MAX_VERTEX_NUM];
    
    typedef struct LGraph{
        VertexLink vertices;
        int vexnum, edgenum;
    
    };
    
    void AddEdge(LGraph *graph, int head, int tail){
        //new a adj node
       adjnode *newadjnode = (adjnode*)malloc(sizeof(struct adjnode));
       if(!newadjnode)
         exit(EXIT_FAILURE);
       newadjnode->index = tail;
       newadjnode->adjnext = NULL;
       adjnode *temp;
    
       temp = graph->vertices[head].firstadj;
       cout<<"this edge: "<<head<<"->"<<newadjnode->index<<endl;
       newadjnode->adjnext =temp;
       graph->vertices[head].firstadj = newadjnode;
       //debug
    cout<<"line: "<<__LINE__;
    cout<<" first adj index: "<<graph->vertices[head].firstadj->index<<endl;
    
    }
    
    LGraph* CreateGraph(LGraph *graph){
        graph = (LGraph*)malloc(sizeof(struct LGraph));
        if(!graph)
           exit(EXIT_FAILURE);
        cout<<"enter the vertex number and edge number:"<<endl;
        cin>>graph->vexnum>>graph->edgenum;
    
        //initialize the vertexes
        for(int v = 0; v < graph->vexnum + 1; v++){
            graph->vertices[v].firstadj = NULL;
        }
    
        //initialize the edge
        int i, j;
        for(int e = 0; e < graph->edgenum; e++){
            cout<<"enter edge of graph:"<<endl;
            cin>>i>>j;
            AddEdge(graph, i, j);
        }
        cout<<"graph.vertex number: "<<graph->vexnum<<endl;
        return graph;
    }
    
    void print(LGraph graph){
        adjnode *temp = NULL;
        for(int i = 1; i < graph.vexnum + 1; i++){
            cout<<"vertex: "<<i;
            temp = graph.vertices[i].firstadj;
           // cout<<"temp"<<temp<<endl;
            while(temp){
                cout<<" adj vertex: "<<temp->index<<endl;
                temp = temp->adjnext;
            }
        }
        cout<<endl;
    }
    


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    html设置360兼容/极速模式
    es查询备忘录
    TypeError: __init__() got an unexpected keyword argument 'strict'
    pandas处理csv
    scrapy中cookie处理
    滑动验证码破解(一)
    python 自定义属性访问 __setattr__, __getattr__,__getattribute__, __call__
    数据库的增删改、单表查询
    库的操作,表的操作,数据类型,完整性约束
    Mysql常用命令(二)
  • 原文地址:https://www.cnblogs.com/wenwangt/p/4925405.html
Copyright © 2020-2023  润新知