关于图的算法,记录对于图的理解

关于图的算法

  • Dargon
  • 2021/01/24
  • 所遇到的的重要的问题: 加深自己能理解 或者记住自己现阶段对于的算法理解
  • 教科书 来自:《大话数据结构》第七章 图

01 深度优先遍历(Deepth_First_Search)

  1. 事实上 深度优先遍历就是一个,深度优先函数进行递归的过程,他从图中某个顶点Vertex出发,访问此顶点,然后从v的未被访问的邻接点出发进行 开始深度优先遍历图,直到图中所有的和V有路径相通的顶点都被访问到。
  2. 主要感觉 当递归返回上一层这种感觉时候,可以处理掉上一层的点,就能解决一些很大问题。

1.1 邻接矩阵的实现

  1. 关于代码:
/* 深度优先递归 */
void DFS_matrix( GraphMatrix G, int i ) {
   
    int j;
    visited[i] =TRUE;
    printf("%c", G.vexs[i]);
    for( j =0; j <G.numVertexes; j++ ) {
   
        // 递归思想真舒服!一层一层去看待问题 想一想走出迷宫点灯的问题!! 
        if( G.arc[i][j] ==TRUE && !visited[j] ) {
    
            DFS_matrix( G, j );
        }
    }
}
/* 深度遍历算法 */
void DFS_matrix_traverse( GraphMatrix G ) {
   
    int i;
    /* 初始化numVertexes 个顶点状态 visited[] 矩阵 */
    for( i =0; i <G.numVertexes; i++ ) {
   
        visited[i] =FALSE;
    }
    // 对 未访问 过的顶点调用 DFS,若是连通图 只会执行一次 
    for( i =0; i <G.numVertexes; i++ ) {
   
        if( !visited[i] ) {
   
            DFS_matrix( G, i );
        }
    }
}
  1. 对于一个图,找一个顶点,按照一个规定方向,递归开始,比如在迷宫问题中 从右边开始走,到一个顶点,当作起始点,再次递归进行(对于其他的,没有查看到的顶点,在递归返回到上一层后 会顺带解决它们)。
  2. 所以对于一个图来说,如果顶点都是联通的话,从一个顶点开始,直接通过递归就可以将所有的顶点都能访问到。

1.2 邻接表的实现

  1. 关于代码:
  2. 理解:
    对于访问的顶点,利用递归调用的时候,使用链表指针代替for循环。

02 广度优先遍历(Breadth_First_Search)

  1. 图的深度优先搜索类似树的前序遍历, 则广度优先遍历类似于 层序遍历,大概理解 我走的不深 不是一头扎下去走到最后,而是一层一层的去访问(Vertex)节点。

2.1 邻接矩阵的实现

  1. 关于代码:
void BFS_matrix_traverse( GraphMatrix G ) {
   
    int i, j;
    QueueNode Q;
    /* 进行初始化 */
    for( i =0; i <G.numVertexes; i++ ) {
   
        visited[i] =FALSE;
    }
    queue_init( &Q );
    /* 对于每一个顶点做循环处理 */
    for( i =0; i <G.numVertexes; i++ ) {
   
        /* 若是没有访问 就对该顶点进行处理 */
        if( !visited[i] ) {
   
            visited[i] =TRUE;
            printf("%c", G.vexs[i]);
            queue_add( &Q, i ); /* 将此顶点入列 */
            while( !queue_empty( Q ) ) {
   
                queue_delete( &Q, &i ); /* 将队中元素 出列 把值赋予 i */
                for( j =0; j <G.numVertexes; j ++ ) {
   
                    if( G.arc[i][j] ==1 && !visited[j] ) {
   
                        visited[j] =TRUE; /* 把与第 i 行邻接的 都去访问 层序遍历 */
                        printf("%c", G.vexs[j]);
                        queue_add( &Q, j );
                    }
                }
            }
        }
    }
}
  1. 从一个顶点(Vertex)开始,将此顶点入队列,在while()循环中,再将顶点弹出队列,保留下标值,然后找与此顶点所链接的顶点 分别操作 标记为已访问,然后进入队列。
  2. 再次进入while() 循环,将第一个连接点 弹出队列,标记访问其连接点 并进行入队。
  3. 这就基本形成 一层一层 进行访问的效果, 层序遍历。

2.2 邻接表的实现

  1. 关于代码:
  2. 理解:
    将while()里面的循环,将与顶点(Vertex)的连接点,变成指针链表去寻找下一个节点,不是依靠矩阵去搜寻。

03 最小生成树(Minimum Cost Spanning Tree)

  1. 将一颗具有(n)个顶点Vertex的图,生成一个具有(n-1)条边的树,且在边中具有权值的时候,将所有的权值综合尽量的小 就是所谓的最小生成树。

3.1 普利姆算法(Prim Algorithm)

  1. 关于代码:
void mini_span_tree_prim(GraphMatrix G) {
   
    int min, i, j, k;
    int adjvex[MAXVEX];  /* 保存相关顶点下标 */
    int lowcost[MAXVEX]; /* 保存相关顶点间的权值 */

    lowcost[0] =0; /* 初始化第一个权值 为0 */
    adjvex[0] =0;  /* 初始化第一个顶点下标为0 */

    /* 初始化 */
    for( i =1; i <G.numVertexes; i++ ) {
   
        lowcost[i] =G.arc[0][i]; /* 将V0顶点与之有边的权值存入数组 相当于初始化 读入V0 行 */
        adjvex[i] =0; /* 初始化都为 V0 的下标 */
    }

    /* 开始运行 找最小的代价问题 */
    for( i =1; i <G.numVertexes; i++ ) {
   
        min =INFI;
        j =1;
        k =0;
        /* 寻找lowcost[] 里面最小值 对应的位置 就是下标 */
        while( j <G.numVertexes ) {
   
            if
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值