图的两种遍历

两种遍历方法都使用了Visited[]这个数组来记录已经访问的节点

DFS(广度优先)

从头结点开始递归的来调用相邻的节点

void Visit( Vertex V )
{
    printf("正在访问顶点%d\n", V);
}

/* Visited[]为全局变量,已经初始化为false */
void DFS( LGraph Graph, Vertex V, void (*Visit)(Vertex) )
{   /* 以V为出发点对邻接表存储的图Graph进行DFS搜索 */
    PtrToAdjVNode W;

    Visit( V ); /* 访问第V个顶点 */
    Visited[V] = true; /* 标记V已访问 */

    for( W=Graph->G[V].FirstEdge; W; W=W->Next ) /* 对V的每个邻接点W->AdjV */
        if ( !Visited[W->AdjV] )    /* 若W->AdjV未被访问 */
            DFS( Graph, W->AdjV, Visit );    /* 则递归访问之 */
}

BFS:

采用队列的方式把一个节点的相邻节点都放到队列里边去 并且当这个节点的邻接点全部被加入到队列中的时候从队列中弹出一个元素在访问他的邻接点

/* 邻接矩阵存储的图 - BFS */

/* IsEdge(Graph, V, W)检查<V, W>是否图Graph中的一条边,即W是否V的邻接点。  */
/* 此函数根据图的不同类型要做不同的实现,关键取决于对不存在的边的表示方法。*/
/* 例如对有权图, 如果不存在的边被初始化为INFINITY, 则函数实现如下:         */
bool IsEdge( MGraph Graph, Vertex V, Vertex W )
{
    return Graph->G[V][W]<INFINITY ? true : false;
}

/* Visited[]为全局变量,已经初始化为false */
void BFS ( MGraph Graph, Vertex S, void (*Visit)(Vertex) )
{   /* 以S为出发点对邻接矩阵存储的图Graph进行BFS搜索 */
    Queue Q;
    Vertex V, W;

    Q = CreateQueue( MaxSize ); /* 创建空队列, MaxSize为外部定义的常数 */
    /* 访问顶点S:此处可根据具体访问需要改写 */
    Visit( S );
    Visited[S] = true; /* 标记S已访问 */
    AddQ(Q, S); /* S入队列 */

    while ( !IsEmpty(Q) ) {
        V = DeleteQ(Q);  /* 弹出V */
        for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */
            /* 若W是V的邻接点并且未访问过 */
            if ( !Visited[W] && IsEdge(Graph, V, W) ) {
                /* 访问顶点W */
                Visit( W );
                Visited[W] = true; /* 标记W已访问 */
                AddQ(Q, W); /* W入队列 */
            }
    } /* while结束*/
}
时间: 2024-10-10 02:33:33

图的两种遍历的相关文章

邻接矩阵(以顶点为中心),比较稀疏时,采用邻接表;图的两种遍历(邻接矩阵实现)

对于边比较稠密的图,可以采用邻接矩阵(以顶点为中心)的方式表示,而边比较稀疏时,采用邻接表的结构更合适.两种都不能直观表达哪两个点相连或者最短路径是什么. 深度优先遍历类似于树的先根序遍历.与树不同的是,它需要对已经访问过的节点添加标记以免被重复遍历. public class Depth { /** * 对k号节点深度遍历 * @param a * @param color * @param k 节点 */ public static void depthTraversal(int[][] a

图的两种遍历方式

图的遍历有两种:深度优先和广度优先.本文中,深度优先使用递归实现,每次递归找到第一个与当前结点相连且未输出过的结点继续往下递归,直至所有结点都已输出.广度优先将开始结点的所有邻接结点全部压入栈,当栈不为空时一直循环将栈首的结点的所有相邻结点压入栈. 具体代码实现如下: 1 //邻接链表 2 class Graph { 3 private: 4 //n: number of nodes 5 int n; 6 vector<int> *edges; 7 bool *visited; 8 publi

图的两种遍历-DFS&amp;BFS

DFS和BFS在图中的应用: 图连通性判定:路径的存在性:图中是否存在环:求图的最小生成树:求图的关键路径:求图的拓扑排序. DFS:简单的说,先一直往深处走,直到不能再深了,再从另一条路开始往深处走,直到所有路都走完: struct node { int next; //E[i].next指向图中与i同父的下一个结点 int to; //E[i].to指向图中i的子结点 }E[110]; int N; int fa[110]; //记录各点的父结点 bool vis[110]; //记录这个点

图的两种存储(邻接矩阵和邻接表)和两种遍历(DFS和BFS)

图的表示有很多,形式不固定,我暂时先记录我已经懂了的,能写的两种即大多数人应该都知道的邻接矩阵和邻接表. 邻接矩阵: 这里的邻接矩阵和离散数学说的有一点不同,至少有向图的邻接矩阵不同(离散书上的有向图的邻接矩阵求法到是有点像求任意两点的最短路径的Floyd算法) 以上都是(我现有知识认为的)废话: 重点 : G : 表示图: Nv:表示图的点数: Ne:表示图的边数: 邻接矩阵 即是一个 Nv * Nv 的矩阵,矩阵是用来储存  权值的(如果是带权图且有边的话),如果是无权图的的话,如果两顶点有

HTML中设置背景图的两种方式

HTML中设置背景图的两种方式 1.background    background:url(images/search.png) no-repeat top; 2.background-image    background-image:url(images/search.png):    background-repeat:no-repeat;

List集合中两种遍历方式

遍历List集合中的元素的方法有两种: 第一种:利用迭代器遍历 代码1: // 迭代器 Iterator it=list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } 或者代码2: for(Iterator it=list.iterator();it.hasNext();) { System.out.println(it.next()); }// 与while循环相比优点:对象it在循环结束后,变为垃圾,自动

根据二叉树的两种遍历求二叉树的结构

二叉树的前序遍历顺序是:根节点,左树,右树 中序遍历顺序是:左树,根节点,右树 后序遍历顺序是:左树,右树,根节点 上面这棵树的前序遍历是:abfcjm   中序遍历是:fbcamj  后序遍历是:fcbmja 根据前序遍历和后序遍历是不能求出树的唯一结构的, 已知的两种遍历顺序必须必须包括中序遍历,因为中序遍历能够递归的推出根节点的左树和右树 如上题已知   前序遍历是:abfcjm   中序遍历是:fbcamj  那么根据前序遍历就可以知道树根是a, 再根据中序遍历就可以知道以a为根节点左树

Map的两种遍历方式

********************************************************************************* *****************************Map两种遍历方式******************************* ********************************************************************************* 1 package ccms;

Map集合的两种遍历方式

Map集合:即 接口Map<K,V> map集合的两种取出方式:    1.Set<k> keyset: 将map中所有的键存入到set集合(即将所有的key值存入到set中), 因为Set具备迭代器,可以进行迭代遍历. 所有可以迭代方式取出所有的链,再根据get方法.获取每一个键对应的值. Map 集合的取出原理: 将map集合转成set集合. 再通过迭代器取出    2. set<Map.Entry<k,v>>  entrySet: 将map集合中的映射