美文网首页
先深遍历

先深遍历

作者: 喜忧参半 | 来源:发表于2021-10-25 11:35 被阅读0次

图结构

邻接矩阵的存储方式
                         (需要与矩阵压缩重点复习)

① 二维数组存储
②一维数组压缩存储
很显然一维数组压缩存储方式,只严格存储下三角部分。
第0行不存元素,第1行存储一个元素,第二行存储2个元素…,第n-1行存储n-1个元素,共需要存储:
1+2+…+(n-1)=n(n-1)/2

邻接表的存储方式

①边结点结构

typedef struct edge_node
{
     int adjacent;           //编号域
     cost_type cost;         //长度域
     struct edge_node *next;     //边结点的next指针
}edge_node,*Eptr;            

②0/1图的边结点结构

typedef struct edge_node    //边结点
{
    int adjacent;           //编号域
    struct edge_node *next;     //边结点的next指针
}edge_node,*Eptr;  

邻接链表的表头结点(顶点结点)结构

typedef struct 
{
    Vname_type name;
    Eptr firsedge;
}    hnode;

先深搜索遍历算法

void dfsmian()                    
{
    int v;                      //   结点变量
    for(v=0;v<n;n++)L[v].mark=0;   //循环将每一个结点标记值清零
    for(v=0;v<n;n++)               //对每一个标记值进行判断
    {
        if(L[v].mark==0)           //如果没有标记过
            dfs(v);                  //对该结点进行dfs
    }
}

void dfs(int v)                    
{
    Eptr p; int w;               //创建一个新的结点,结点变量
    visit(v);                    //对结点v进行访问
    L[v].mark=1;                    //标记该结点代表已经访问过
    p=L[v].firstedge;      //指向已经访问过的结点的邻接表的首结点
    while(p!=NULL)                   //当邻接表的首结点存在时
    {
        w=p->adjacent;               //将编号赋给新结点w
        if(L[w].mark==0)            //如果新结点w未被访问过
            dfs(w);                  //访问新结点w
        p=p->next;            //递归结束后,结点下移
    }
}
求无向图的连通分量的算法
void dfsmian()
{
    int v,k=0;
    for(v=0;v<n;v++)L[v].mark=0;
    for(v=0;v<n;v++)
    {
        if (L[v].mark==0)
        {
            k++;
            printf("第%d个连通分量的顶点集:\n {",k);
            dfs(v);
            printf(" }\n");
        }
    }
}
求无向图先深生成树的算法
void dfsmian()                    
{
    int v;                      //   结点变量
    for(v=0;v<n;n++)L[v].mark=0;   //循环将每一个结点标记值清零
    for(v=0;v<n;n++)               //对每一个标记值进行判断
    {
        if(L[v].mark==0)           //如果没有标记过
       {
            将(v,w)加进树边集;
            dfs(v);                  //对该结点进行dfs
       }
    }
}
判断有向图是否存在回路的算法
int cycle;                     //cycle是整体量,"有回路否"标记

void dfsmian()                    
{
    int v;                      //   结点变量
    cycle=0;
    for(v=0;v<n;n++)L[v].mark=0;   //循环将每一个结点标记值清零
    for(v=0;v<n;n++)               //对每一个标记值进行判断
    {
        if(L[v].mark==0)           //如果没有标记过
            dfs(v);                  //对该结点进行dfs
        if(cycle)
            printf("图中有回路\n");
        else
            printf("图中没有回路\n");
    }
}

void dfs(int v)                    
{
    Eptr p; int w;               //创建一个新的结点,结点变量
    visit(v);                    //对结点v进行访问
    L[v].mark=1;                    //标记该结点代表已经访问过
    p=L[v].firstedge;      //指向已经访问过的结点的邻接表的首结点
    while(p!=NULL)                   //当邻接表的首结点存在时
    {
        w=p->adjacent;               //将编号赋给新结点w
        if(L[w].mark==0)            //如果新结点w未被访问过
            dfs(w);                  //访问新结点w
        else if(L[w].mark==1)     //dfs(w)尚未终止,置有回路标记
              cycle=1;
        p=p->next;            //递归结束后,结点下移
    }
    L[v].mark=2;            //置dfs(v)终止标记
}
求无向连通图关节点的算法
int count=0;root_sons=0;
void dfsmian()                    
{
    int v;                      //   结点变量
    for(v=0;v<n;n++)
         L[v].mark=0;   //对顶点作未标记访问
     v=0;
     L[v].father=0;
     dfs(v);
     if(root_sons>1)
        printf("%s\n",L[v].name);     
}
void dfs(int v)
{
    Eptr p; int w;
    L[v].mark=1;
    L[v].low=L[v].dfnumb=++count;  //置v的先深编号和low(v)初值
    p=L[v].firstedge;
    while(p)
    {
        w=p->adjacent;
        if(L[w].mark==0)
        {
            L[w].father=v;    //使w作v的儿子,递归调用
            dfs(w);
            if(L[v].dfnumb==1)//若v是根,根的儿子计数加1
                root_sons++;
            else                  //若不是
                if(L[w].low>=L[v].dfnumb) //发现v是关结点
                    if(v没被输出过)
                        printf("%s\n",L[v].name);//输出关结点名
                if(L[v].low>L[w].low)
                    L[v].low=L[w].low;
                             //使父亲v的low值不大于儿子w的low值
        }
        else //L[w].mark 不等于 0,表示 w 已被访问过
         if(L[v].father!=w && L[v].low> L[w].dfnumb)
            L[v].low=L[w].dfnumb;
                    //若 w 不是 v 的父亲,则(v,w)是回边
            p=p->next;
    }
}

相关文章

  • 先深遍历

    图结构 邻接矩阵的存储方式 ① 二维数组存储②一维数组压缩存储很显然一维数组压缩存储方式,只严格存储下三角部分。第...

  • 先深遍历

    先深遍历 dfsmain功能:先将所有结点标记置零,然后从0开始循环,对每个结点进行标记判断,若未标记过执行dfs...

  • 二叉树的递归遍历

    【链表存储结构】 【先序遍历】先访问根节点,先序遍历其左子树,先序遍历其右子树。 【中序遍历】 【后序遍历】

  • 二叉树的遍历算法

    递归版本 先序遍历: 中序遍历: 后序遍历: 非递归版本 先序遍历: 中序遍历: 后序遍历: 层次遍历:

  • 二叉树。

    一. 先序遍历是:先遍历局部的根节点,然后便利左右子树。 中序遍历是:先遍历左子树,遍历局部的根节点,遍历右子树。...

  • N叉树的后序遍历

    题目: 题目的理解: 后序遍历和前序遍历遍历理解:前序遍历:先保存值,然后遍历子节点。后序遍历:先遍历子节点,然后...

  • 二叉树遍历算法

    二叉树遍历算法有4种,先序、中序、后序和层序遍历 先序遍历:先根、后左、再右中序遍历:先左、后根、再右后序遍历:先...

  • java二叉树三种遍历实现

    先序遍历 后续遍历 中序遍历

  • 二叉树的遍历

    树的遍历顺序大体分为三种:前序遍历(先根遍历、先序遍历)中序遍历(中根遍历)后序遍历(后根遍历)关注点是根。

  • 二叉树遍历算法

    图文解说 1、先序遍历又称为根左右 遍历规则: 先遍历根节点,然后遍历左节点,最后遍历呦节点。 举例 首先遍历A节...

网友评论

      本文标题:先深遍历

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