美文网首页
数据结构 —— 图的遍历(深度遍历 DFS)

数据结构 —— 图的遍历(深度遍历 DFS)

作者: E术家 | 来源:发表于2020-04-30 17:39 被阅读0次

    每个顶点有且只被访问1次

    深度遍历

    通过右手原则走向
    1.A —— B,F 选B
    2.B —— A,C,I,G 选C
    3.C —— D,I,B 选D
    4.D —— I,H,G,E 选E
    4.E —— D,H,F 选F
    5.F —— E,G,A 选G
    6.G —— F,B,D,H 选H
    7.H —— G,D,E 都选中过了 反向循环 回溯到G
    8.G —— 没有未选项 回溯到F
    9.F —— 没有未选项 回溯到E
    10.E —— 没有未选项 回溯D
    11.D —— 存在未选项I 选I 回溯到C
    12.C —— 没有未选项 回溯到B
    13.B —— 没有未选项 回溯到A 结束


    邻接矩阵代码实现

    基础设置

    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    
    typedef int Status;    /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
    typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
    
    typedef char VertexType; /* 顶点类型应由用户定义 */
    typedef int EdgeType; /* 边上的权值类型应由用户定义 */
    
    #define MAXSIZE 9 /* 存储空间初始分配量 */
    #define MAXEDGE 15
    #define MAXVEX 9
    #define INFINITYC 65535
    
    typedef struct {
        VertexType vexs[MAXVEX]; /* 顶点表 */
        EdgeType arc[MAXVEX][MAXVEX];/* 邻接矩阵,可看作边表 */
        int numVertexes, numEdges; /* 图中当前的顶点数和边数 */
    }MGraph;
    

    构建一个邻接矩阵

    void CreateMGraph(MGraph *G) {
        int i, j;
        
        //1. 确定图的顶点数以及边数
        G->numEdges=15;
        G->numVertexes=9;
        
        /*2.读入顶点信息,建立顶点表 */
        G->vexs[0]='A';
        G->vexs[1]='B';
        G->vexs[2]='C';
        G->vexs[3]='D';
        G->vexs[4]='E';
        G->vexs[5]='F';
        G->vexs[6]='G';
        G->vexs[7]='H';
        G->vexs[8]='I';
        
        /*3. 初始化图中的边表*/
        for (i = 0; i < G->numVertexes; i++)
        {
            for ( j = 0; j < G->numVertexes; j++)
            {
                G->arc[i][j]=0;
            }
        }
        
        /*4.将图中的连接信息输入到边表中*/
        G->arc[0][1]=1;
        G->arc[0][5]=1;
        
        G->arc[1][2]=1;
        G->arc[1][8]=1;
        G->arc[1][6]=1;
        
        G->arc[2][3]=1;
        G->arc[2][8]=1;
        
        G->arc[3][4]=1;
        G->arc[3][7]=1;
        G->arc[3][6]=1;
        G->arc[3][8]=1;
        
        G->arc[4][5]=1;
        G->arc[4][7]=1;
        
        G->arc[5][6]=1;
        
        G->arc[6][7]=1;
        
        /*5.无向图是对称矩阵.构成对称*/
        for(i = 0; i < G->numVertexes; i++)
        {
            for(j = i; j < G->numVertexes; j++)
            {
                G->arc[j][i] =G->arc[i][j];
            }
        }
    }
    

    遍历

    Boolean visited[MAXVEX]; /* 访问标志的数组 */
    //1. 标识顶点是否被标记过;
    //2. 选择从某一个顶点开始(注意:非连通图的情况)
    //3. 进入递归,打印i点信息,标识; 边表
    //4. [i][j] 是否等于1,没有变遍历过visted
    void DFS(MGraph G,int i){
        //1.
        visited[i] = TRUE;
        printf("%c",G.vexs[i]);
        
        //2.0~numVertexes
        for(int j = 0; j < G.numVertexes;j++){
            if(G.arc[i][j] == 1 && !visited[j])
                DFS(G, j);
        }
    }
    
    void DFSTravese(MGraph G){
        //1.初始化
        for(int i=0;i<G.numVertexes;i++){
            visited[i] = FALSE;
        }
        
        //2.某一个顶点
        for(int i = 0;i<G.numVertexes;i++){
            if(!visited[i]){
                DFS(G, i);
            }
        }
    }
    

    邻接表代码实现

    基础设置

    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    
    #define MAXSIZE 9 /* 存储空间初始分配量 */
    #define MAXEDGE 15
    #define MAXVEX 9
    #define INFINITYC 65535
    
    typedef int Status;    /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
    typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
    
    typedef char VertexType; /* 顶点类型应由用户定义 */
    typedef int EdgeType; /* 边上的权值类型应由用户定义 */
    
    /* 邻接矩阵结构 */
    typedef struct {
        VertexType vexs[MAXVEX]; /* 顶点表 */
        EdgeType arc[MAXVEX][MAXVEX];/* 邻接矩阵,可看作边表 */
        int numVertexes, numEdges; /* 图中当前的顶点数和边数 */
    }MGraph;
    
    /* 邻接表结构****************** */
    typedef struct EdgeNode /* 边表结点 */
    {
        int adjvex;    /* 邻接点域,存储该顶点对应的下标 */
        int weight;        /* 用于存储权值,对于非网图可以不需要 */
        struct EdgeNode *next; /* 链域,指向下一个邻接点 */
    }EdgeNode;
    
    typedef struct VertexNode /* 顶点表结点 */
    {
        int in;    /* 顶点入度 */
        char data; /* 顶点域,存储顶点信息 */
        EdgeNode *firstedge;/* 边表头指针 */
    }VertexNode, AdjList[MAXVEX];
    
    typedef struct {
        AdjList adjList;
        int numVertexes,numEdges; /* 图中当前顶点数和边数 */
    }graphAdjList,*GraphAdjList;
    

    构建一个邻接矩阵

    void CreateMGraph(MGraph *G) {
        int i, j;
        
        //1. 确定图的顶点数以及边数
        G->numEdges=15;
        G->numVertexes=9;
        
        /*2.读入顶点信息,建立顶点表 */
        G->vexs[0]='A';
        G->vexs[1]='B';
        G->vexs[2]='C';
        G->vexs[3]='D';
        G->vexs[4]='E';
        G->vexs[5]='F';
        G->vexs[6]='G';
        G->vexs[7]='H';
        G->vexs[8]='I';
        
        /*3. 初始化图中的边表*/
        for (i = 0; i < G->numVertexes; i++)
        {
            for ( j = 0; j < G->numVertexes; j++)
            {
                G->arc[i][j]=0;
            }
        }
        
        /*4.将图中的连接信息输入到边表中*/
        G->arc[0][1]=1;
        G->arc[0][5]=1;
        
        G->arc[1][2]=1;
        G->arc[1][8]=1;
        G->arc[1][6]=1;
        
        G->arc[2][3]=1;
        G->arc[2][8]=1;
        
        G->arc[3][4]=1;
        G->arc[3][7]=1;
        G->arc[3][6]=1;
        G->arc[3][8]=1;
        
        G->arc[4][5]=1;
        G->arc[4][7]=1;
        
        G->arc[5][6]=1;
        
        G->arc[6][7]=1;
        
        /*5.无向图是对称矩阵.构成对称*/
        for(i = 0; i < G->numVertexes; i++)
        {
            for(j = i; j < G->numVertexes; j++)
            {
                G->arc[j][i] =G->arc[i][j];
            }
        }
    }
    

    利用邻接矩阵构建邻接表

    void CreateALGraph(MGraph G,GraphAdjList *GL){
        
        //1.创建邻接表,并且设计邻接表的顶点数以及弧数
        *GL = (GraphAdjList)malloc(sizeof(graphAdjList));
        (*GL)->numVertexes = G.numVertexes;
        (*GL)->numEdges = G.numEdges;
        
        //2. 从邻接矩阵中将顶点信息输入
        for (int i = 0; i < G.numVertexes; i++) {
            //顶点入度为0
            (*GL)->adjList[i].in = 0;
            //顶点信息
            (*GL)->adjList[i].data = G.vexs[i];
            //顶点边表置空
            (*GL)->adjList[i].firstedge = NULL;
        }
        
        //3. 建立边表
        EdgeNode *e;
        for (int i = 0; i < G.numVertexes; i++) {
            for (int j = 0; j < G.numVertexes; j++) {
                if (G.arc[i][j] == 1) {
                 
                    //创建边表中的邻近结点 i->j
                    e = (EdgeNode *)malloc(sizeof(EdgeNode));
                    //邻接序号为j
                    e->adjvex = j;
                    //将当前结点的指向adjList[i]的顶点边表上
                    e->next = (*GL)->adjList[i].firstedge;
                    (*GL)->adjList[i].firstedge = e;
                    //顶点j 上的入度++;
                    (*GL)->adjList[j].in++;
                    
    //                //创建边表中的邻近结点 j->i
    //                e = (EdgeNode *)malloc(sizeof(EdgeNode));
    //                //邻接序号为j
    //                e->adjvex = i;
    //                //将当前结点的指向adjList[i]的顶点边表上
    //                e->next = (*GL)->adjList[j].firstedge;
    //                (*GL)->adjList[j].firstedge = e;
    //                //顶点j 上的入度++;
    //                (*GL)->adjList[i].in++;
                }
            }
        }
    }
    

    递归算法

    Boolean visited[MAXSIZE]; /* 访问标志的数组 */
    /* 邻接表的深度优先递归算法 */
    void DFS(GraphAdjList GL, int i) {
        EdgeNode *p;
        visited[i] = TRUE;
        
        //2.打印顶点 A
        printf("%c ",GL->adjList[i].data);
        
        p = GL->adjList[i].firstedge;
        
        //3.
        while (p) {
            if(!visited[p->adjvex])
                DFS(GL,p->adjvex);
            
            p = p->next;
        }
        
    }
    

    遍历

    void DFSTraverse(GraphAdjList GL) {
        //1. 将访问记录数组默认置为FALSE
        for (int i = 0; i < GL->numVertexes; i++) {
            /*初始化所有顶点状态都是未访问过的状态*/
            visited[i] = FALSE;
        }
    
        //2. 选择一个顶点开始DFS遍历. 例如A
        for(int i = 0; i < GL->numVertexes; i++)
            //对未访问过的顶点调用DFS, 若是连通图则只会执行一次.
            if(!visited[i])
                DFS(GL, i);
    }
    

    main函数实现

    int main(int argc, const char * argv[]) {
        // insert code here...
        printf("邻接表的深度优先遍历!\n");
        MGraph G;
        GraphAdjList GL;
        CreateMGraph(&G);
        CreateALGraph(G,&GL);
      
        
        DFSTraverse(GL);
        printf("\n");
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:数据结构 —— 图的遍历(深度遍历 DFS)

          本文链接:https://www.haomeiwen.com/subject/mcrtghtx.html