数据结构之DFS(邻接表版)

本文介绍了图的深度优先搜索(DFS)算法,并详细解释了其基本思想与实现过程。通过一个具体的邻接表实现示例,展示了如何使用递归方法进行DFS遍历,包括创建邻接表、遍历图以及打印DFS序列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图的遍历 是指从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次。
图的遍历是图的基本操作之一,很多需要对图中每个顶点依次进行的操作都可以在遍历中完成。图的遍历通常有 深度优先搜索和广度优先搜索

深度优先搜索(Depth-First Search)

深度优先搜索的基本思想如下:
1、从图中某个顶点Vi出发,首先访问Vi
2、选择一个与刚访问过的顶点Vi相邻接且未访问过的顶点Vj,然后访问该顶点。以该顶点为新顶点,重复本步骤,直到当前顶点没有未访问的邻接点为止。
3、返回前一个访问过的且仍有未访问的邻接点的顶点,找出并访问该顶点的下一个未访问的邻接点,然后执行步骤 2。

PS:若访问的是非连通图,我们从某个顶点出发进行深度优先搜索后,则该顶点所在的连通分量的所有顶点都将被访问。此时,若图中还有顶点未访问,则另选图中一个未访问的顶点作为起始点,重复上述深度优先搜索过程,直至图中所有顶点均访问过为止。

对图进行深度优先搜索时,按访问顶点的先后次序得到的顶点的序列称为图的深度优先搜索序列,简称DFS序列。一个图的DFS序列可能不唯一,它与所采用的算法的存储结构和初始出发点密切相关。

邻接表版的DFS

完整代码

#include<stdio.h>
#include<malloc.h>
#define max 100
typedef struct node
{
    int adjvex;
    struct node*next;
}arcnode;
typedef struct 
{
    int vertex;
    arcnode*firstarc;
}vexnode;
vexnode adjlist[max];
int creatadjlist()
{
    arcnode*ptr;
    int arcnum,vexnum,k,v1,v2;
    printf("input the vexnum,arcnum:");
    scanf("%d,%d",&vexnum,&arcnum);
    for(k=1;k<=vexnum;k++)
        adjlist[k].firstarc=0;
    for(k=0;k<arcnum;k++)
    {
        printf("v1,v2=");scanf("%d,%d",&v1,&v2);
        ptr=(arcnode*)malloc(sizeof(arcnode));
        ptr->adjvex=v2;
        ptr->next=adjlist[v1].firstarc;
        adjlist[v1].firstarc=ptr;
        ptr=(arcnode*)malloc(sizeof(arcnode));
        ptr->adjvex=v1;
        ptr->next=adjlist[v2].firstarc;
        adjlist[v2].firstarc=ptr;
    }
    return vexnum;
}
void dfs(int *v)
{
    int *w;
    arcnode*p;
    p=adjlist[*v].firstarc;
    printf("%d  ",*v);
    adjlist[*v].vertex=1;
    while(p!=NULL)
    {
        *w=p->adjvex;
        if(adjlist[*v].vertex==0)
        dfs(w);
        p=p->next;
    }
}
int main()
{
    int i,n,*v;
    arcnode*p;
    n=creatadjlist();
    printf("the Adjacency List:\n");
    for(i=1;i<=n;i++)
    {
        printf("%d==>",i);
        p=adjlist[i].firstarc;
        while(p!=NULL)
        {
            printf("----->%d",p->adjvex);
            p=p->next;
        }
        putchar('\n');
    }
    printf("the dfs's node v is:");scanf("%d",v);
    printf("the dfs:");dfs(v);
    return 0;
}

这里写图片描述

总结
DFS的核心就是不断的访问顶点,本例采用的是较为普遍的做法,设置一个标志(adjlist[v].vertex),若标志等于1则表明访问过,若标志等于0则未访问过,然后再进行递归,当然递归传参记得用引用,不然是不会起到什么效果的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值