图的DFS与BFS遍历

一、图的基本概念

1、邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点;对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1邻接点。

2、度:就是与该顶点相互关联的弧的个数。

3、连通图:无向图的每个顶点之间都有可达路径,则称该无向图为连通图。有向图每个顶点之间都有<v1,v2>和<v2,v1>,则称此有向图为强连通图

二、存储结构

1、邻接矩阵存储(Adjacency Matrix)

对无权图,顶点之间有弧标1,无弧标0;

对有权图,顶点之间有弧标权,无弧标无穷大;

2、邻接表(看书吧,精力有限不想画图了)

三、DFS与BFS

其实深度优先和广度优先,最重要的是要掌握其思想,而不是具体的实现,因为万变不离其宗。

1、DFS深度优先

①从v0出发访问v0

②找到刚访问过得顶点,访问其未访问过得邻接点中的一个。重复②直到不再有邻接点位置。

③回溯,返回前一个被访问过但是仍有未被访问过得邻接点的顶点,继续访问它的下一个邻接点。重复②直至完全遍历。

可能我描述的不够准确,但那也没有办法,应为有些东西真的是只能意会。学计算机必须要结合具体的例子来看。

原图:

DFS

其实简单来说:就是如果访问到的结点有邻接点就一直向下访问,否则就回溯。同树中的先根遍历很类似。

数据存储结构:

String[] vertex = new String[] {"v0","v1","v2","v3","v4","v5"};
int[][] matrix  = new int[][] {
        {0,1,0,1,0,0},
        {1,0,1,0,1,0},
        {0,1,0,0,0,0},
        {1,0,0,0,0,1},
        {0,1,0,0,0,0},
        {0,0,0,1,0,0}
};
int[] visited = new int[6];//标记访问过得结点

递归实现:

void matrixDFS(int v0) {
    System.out.print(vertex[v0] + " ");
    visited[v0] = 1;
    //遍历寻找v0的邻接点
    for(int i = 0; i < vertex.length; i++) {
        if(matrix[v0][i] == 1 && visited[i] == 0) {
            matrixDFS(i);
        }
    }
}

非递归实现:

//基于栈的非递归实现
void matrixDFS1(int v0) {
    Stack<Integer> stack = new Stack<Integer>();
    stack.push(v0);
    while(!stack.isEmpty()) {
        int v = stack.pop();
        if(visited[v] == 0) {//栈中很可能有重复的元素
            System.out.print(vertex[v] + " ");
            visited[v] = 1;
            for(int i = 0; i < matrix.length; i++) {
                if(matrix[v][i] == 1 && visited[i] == 0) {
                    stack.push(i);
                }
            }
        }
    }
}

 2、BFS深度优先遍历

①访问v0

②访问v0所以未被访问过的邻接点

③分别以这些邻接点(②中的邻接点)出发,去访问他们的邻接点。重复③知道遍历结束。

BFS就比较像树中的层次遍历

代码实现:

void matrixBFS2(int v0) {
    Queue<Integer> queue = new LinkedList<>();
    queue.offer(v0);
    while(!queue.isEmpty()) {
        int v = queue.poll();
        if(visited[v] == 0) {
            System.out.print(vertex[v] + " ");
            visited[v] = 1;
            for(int i = 0; i < vertex.length; i++) {
                if(matrix[v][i] == 1 && visited[i] == 0) {
                    queue.offer(i);
                }
            }
        }
    }
}

可以看到这段代码和DFS递归实现的代码差别只是一个用栈一个用队列。

DFS:访问v0,邻接点如栈

BFS:访问v0,邻接点入队

我们的目标不是要掌握这些具体的实现,而是理解DFS与BFS算法的思想,将其活学活用。

数据结构与算法参考

原文地址:https://www.cnblogs.com/mgblogs/p/11662955.html

时间: 2024-07-28 22:29:25

图的DFS与BFS遍历的相关文章

图的 DFS 与 BFS 复杂度分析

DFS的复杂度分析: 对于邻接表的存储方式:因为邻接表中每条链表上的从第2个结点到表尾结点一定是表头结点的邻接点,所以遍历表头结点的邻接的过程中只需要遍历这些顶点即可,无需遍历其他的顶点,所以遍历某个顶点的所有邻接点的复杂度为O(ei), ei为每个顶点的邻接点个数,也就是每条链表的边数.所以邻接表版的 dfs 遍历所有邻接点的时间复杂度为 O(e1 + e2 + e3 + .... + en) ,因为所有边数之和为 E , 所以时间复杂度为 O(E) , 又因为访问每个顶点都必须被访问一次,

学习笔记:图的DFS和BFS的两种搜索办法

  在学习图结构的过程中,DFS和BFS是两种不同的遍历方式,其寻找元素具有不同的优点和缺陷. BFS被称作广度优先算法, 在遍历整个图的过程中,BFS将采用入队的方式进行,值得一提的是,这和树结构中的层序遍历有很大的相似之处. 在层序遍历中,将父亲节点入队后,在父亲节点出队后,将其儿子节点入队. 同理在图的BFS遍历中,先让BFS的首元素入队,在收元素入队后将他的儿子节点入队,放能够实现BFS搜索,他们的整体思想是一样的. 1 void TraversalGraph_BFS(LGraph Gr

数据结构(11) -- 邻接表存储图的DFS和BFS

/////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS /////////////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> #include <queue> using namespace std; //图的邻接表表示法

树的常见算法&amp;图的DFS和BFS

树及二叉树: 树:(数据结构中常见的树) 树的定义 树的存储:下面介绍三种不同的树的表示法:双亲表示法,.孩子表示法,.孩子兄弟表示法. 双亲表示法 我们假设以一组连续空间存储树的结点,同时在每个结点中,附设一个指示器指向其双亲结点到链表中的位置.也就是说每个结点除了知道自己之外还需要知道它的双亲在哪里. 它的结构特点是如图所示: 以下是我们的双亲表示法的结构定义代码: /*树的双亲表示法结点结构定义 */ #define MAXSIZE 100 typedef int ElemType; //

图的DFS与BFS

1.DFS 深度优先搜索在搜索过程中访问某个顶点后,需要递归地访问此顶点的所有未访问过的相邻顶点. (1)递归实现 #include <iostream> #define N 5 using namespace std; int maze[N][N] = { { 0, 1, 1, 0, 0 }, { 0, 0, 1, 0, 1 }, { 0, 0, 1, 0, 0 }, { 1, 1, 0, 0, 1 }, { 0, 0, 1, 0, 0 } }; int visited[N + 1] = {

图、dfs、bfs

graphdfsbfs 1.clone graph2.copy list with random pointer3.topological sorting4.permutations5.subsets6.n queens7.subsetsII 8.palindrome partitioning9.combination sum10.combination sumII11.word ladder 12.word ladderII 克隆图:先克隆点,再克隆边. 宽度优先搜索有模板,以后告诉了图中的一

算法导论--图的遍历(DFS与BFS)

转载请注明出处:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51897538 图的遍历就是从图中的某个顶点出发,按某种方法对图中的所有顶点访问且仅访问一次.为了保证图中的顶点在遍历过程中仅访问一次,要为每一个顶点设置一个访问标志.通常有两种方法:深度优先搜索(DFS)和广度优先搜索(BFS).这两种算法对有向图与无向图均适用. 以下面无向图为例: 1.深度优先搜索(DFS) 基本步骤: 1.从图中某个顶点v0出发,首先访问v

图的遍历 (dfs与bfs)x

遍历是很多图论算法的基础,所谓图的遍历( graph traversal),也称为搜索( search),就是从图中某个顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次.         遍历可以采取两种方法进行:         深度优先搜索( DFS: depth first search):         广度优先搜索( BFS: breadth first search). 对图进行存储与遍历: 输入: 第一行:顶点数n. 第二行:边数m. 以下m行,每行两个顶点编号u

图的dfs遍历和bfs遍历

对如下图进行广度和深度遍历; dfs遍历,(依次输出遍历顶点): 用邻接矩阵存图(用一个二维数组把图存起来)! <span style="font-size:18px;">#include<stdio.h> #define MAX 9999999//当顶点之间不相通时,标记为一个很大的数 int sum=0;//记录遍历的顶点的个数 int v,s;//顶点数和边数 int book[50]={0},p[30][30];//标记数组和矩阵 void dfs(in