一步一步学数据结构之n--n(图遍历--深度优先遍历--递归实现)

 

 

       今天来介绍下图的遍历,首先说下定义:

       《一步一步学数据结构之n--n(图遍历--深度优先遍历--递归实现)》

       而在这里,就给大家叙述下深度优先遍历。本来是要用自己的话来给大家讲解的,但是搜了下网上的定义,觉得还是网上的定义更可靠和严谨,所以就摘取了百度百科的说明:

       假设给定图G的初态是所有顶点均未曾访问过。在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。

       图的深度优先遍历类似于树的前序遍历。采用的搜索方法的特点是尽可能先对纵深方向进行搜索。这种搜索方法称为深度优先搜索(Depth-First Search)。相应地,用此方法遍历图就很自然地称之为图的深度优先遍历。

如图:

       《一步一步学数据结构之n--n(图遍历--深度优先遍历--递归实现)》

       然后看下算法思想,其实在上述定义中也说过,现在来总结下:

       《一步一步学数据结构之n--n(图遍历--深度优先遍历--递归实现)》

      首先发下用邻接链表法实现的深度优先遍历代码(如果不理解邻接链表法,请在本博客数据结构系列中查找,里面有详细介绍),代码是基于本博客数据结构系列讲解邻接链表法实现图写的,大家可以把这段代码加在那些代码中就可以运行:

static void recursive_dfs(TLGraph* graph, int v, int visited[], LGraph_Printf* pFunc)
{
    int i = 0;
    
    pFunc(graph->v[v]);
    
    visited[v] = 1;
    
    printf(", ");
    
    for(i=0; i<LinkList_Length(graph->la[v]); i++)
    {
        TListNode* node = (TListNode*)LinkList_Get(graph->la[v], i);
        
        if( !visited[node->v] )
        {
            recursive_dfs(graph, node->v, visited, pFunc);
        }
    }
}

void LGraph_DFS(LGraph* graph, int v, LGraph_Printf* pFunc)
{
    TLGraph* tGraph = (TLGraph*)graph;
    int* visited = NULL;
    int condition = (tGraph != NULL);
    
    condition = condition && (0 <= v) && (v < tGraph->count);
    condition = condition && (pFunc != NULL);
    condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);
    
    if( condition )
    {
        int i = 0;
        
        recursive_dfs(tGraph, v, visited, pFunc);
        
        for(i=0; i<tGraph->count; i++)
        {
            if( !visited[i] )
            {
                recursive_dfs(tGraph, i, visited, pFunc);
            }
        }
        
        printf("\n");
    }
    
    free(visited);
}

 

      最后发下用邻接矩阵法实现的深度优先遍历代码(如果不理解邻接矩阵法,请在本博客数据结构系列中查找,里面有详细介绍),代码是基于本博客数据结构系列讲解邻接矩阵法实现图写的,大家可以把这段代码加在那些代码中就可以运行

static void recursive_dfs(TMGraph* graph, int v, int visited[], MGraph_Printf* pFunc)
{
    int i = 0;
    
    pFunc(graph->v[v]);
    
    visited[v] = 1;
    
    printf(", ");
    
    for(i=0; i<graph->count; i++)
    {
        if( (graph->matrix[v][i] != 0) && !visited[i] )
        {
            recursive_dfs(graph, i, visited, pFunc);
        }
    }
}

void MGraph_DFS(MGraph* graph, int v, MGraph_Printf* pFunc)
{
    TMGraph* tGraph = (TMGraph*)graph;
    int* visited = NULL;
    int condition = (tGraph != NULL);
    
    condition = condition && (0 <= v) && (v < tGraph->count);
    condition = condition && (pFunc != NULL);
    condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);
    
    if( condition )
    {
        int i = 0;
        
        recursive_dfs(tGraph, v, visited, pFunc);
        
        for(i=0; i<tGraph->count; i++)
        {
            if( !visited[i] )
            {
                recursive_dfs(tGraph, i, visited, pFunc);
            }
        }
        
        printf("\n");
    }
    
    free(visited);
}

 

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/nethanhan/article/details/9997017
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞