【图算法】(2)DFS和BFS

7 篇文章 0 订阅
4 篇文章 0 订阅

1.DFS思想以及实现

算法描述
访问起始顶点v
当v还有邻接顶点没有被访问时
—–深度遍历未访问过的邻接顶点w
当v的所有邻接顶点都被访问时
—–如果图中所有顶点均已访问时
算法结束
—–如果途中还有未访问的顶点
以未访问顶点作为起始顶点深度遍历

算法实现

//递归dfs函数
static void recursive_dfs(TGraph *graph,int v,int *visied,Graph_Printf *pFunc);

void Graph_DFS(Graph *graph,int v,Graph_Printf *pFunc)
{
    TGraph *t_graph = (TGraph *)graph;
    int *visited = NULL//visited[]用来保存已经访问过的顶点
    int condition = t_graph != NULL;
    //相关参数检验
    visited = (int *)calloc(t_graph->count,sizeof(int));
    condition = condition && (visited != NULL);
    if(condition){
        int i=0;
        //调用dfs递归遍历函数
        recursive_dfs(t_graph,visited,pFunc);
        for(i=0;i<t_graph->count;++i){
            if(!visited[i]){
                //如果存在未被访问过的顶点,继续调用dfs递归遍历
                recursive_dfs(t_graph,visited,pFunc);
            }
        }
        printf("\n");
    }
}

static void recursive_dfs(TGraph *graph,int v,int *visied,Graph_Printf *pFunc)
{
    //参数说明,v表示开始遍历的顶点,visited为存储已经被访问过顶点的数组,pFunc是传入的回调函数,功能是打印被访问的元素
    int i=0;
    pFunc(graph->v[v]);
    visited[v]=1; 
    printf(", ");
    for(i=0;i<graph->count;++i){
        //graph->matrix[v][i]表示v为begin,i为end的边
        if((graph->matrix[v][i]!=0)&&(visited[i]!=1)){
            recursive_dfs(graph,i,visied,pFunc);
        }
    }
}

采用DFS算法遍历结果如图
DFS

2.BFS思想以及实现

算法描述
a.访问起始顶点v0
b.依次访问v0的各个临界点v01,v02,…,v0x
c.当最近一次被访问的顶点依次为vi1,vi2,…,viy
d.依次访问vi1,vi2,…,viy的未被访问的邻接点
重复步骤d,直到所有顶点均被访问
整体来看BFS是一种层次遍历,需要借助队列实现。

算法实现

static void bfs(TGraph *t_graph,int v,int *visited,Graph_printf* pFunc);

void Graph_BFS(Graph *graph,int v,Graph_Printf *pFunc)
{
    TGraph *t_graph = (TGraph *)graph;
    int *visited = NULL;
    int condition = (t_graph != NULL);
    //参数检测
    visited = (int *)calloc(t_graph->count,sizeof(int));
    if(condition)
    {
        int i=0;
        bfs(t_graph,v,visited,pFunc);
        for(i=0;i<t_graph->count;++i){
            if(!visited[i]){
                bfs(t_graph,i,visited,pFunc);
            }
        }
        printf("\n");
    }
    free(visited);
    visited = NULL; 
}

static void bfs(TGraph *t_graph,int v,int *visited,Graph_Print *pFunc)
{
    //借助队列实现
    LinkQueue *queue = LinkQueue_Create();
    if(queue != NULL){
        //起始顶点v入队
        LinkQueue_Append(queue,graph->v+v);
        visited[v]=1;
        while(LinkQueue_Length(queue) > 0){
            //当队列不为空时
            int i=0;
            //出队,记录起始节点,BFS与DFS不同的地方,起始节点固定
            v = (Vertex **)LinkQueue_Retrieve(queue)-graph->v;
            pFunc(graph->v[v]);
            printf(", ");
            for(i=0;i<t_graph->count;++i){
                if((t_graph->matrix[v][i]!=0)&&(visited[i]!=1))
                {
                    LinkQueue_Append(queue,graph->v+i);
                    visited[i]=1;
                }
            }
        }
    }
    LinkQueue_Destroy(queue);
}

运行结果如下:
BFS

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值