当前位置:   article > 正文

DFS和BFS(广度优先搜索和深度优先搜索)5个经典例子_深度优先搜索例子

深度优先搜索例子

题目1

在这里插入图片描述

static String b[] = { "a", "b", "c", "d", "e", "f", "g" };
static int [][]arr= {
			{0,0,1,1,0,1,0},
			{0,0,1,0,0,0,0},
			{1,1,0,1,0,0,0},
			{1,0,1,0,0,0,0},
			{0,0,0,0,0,0,1},
			{1,0,0,0,0,0,1},
			{0,0,0,0,1,1,0}
	};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

对此二维数组进行深度搜索与广度搜索,并遍历结果。

深搜结果
a c b d f g e
广搜结果
a c d f b g e

深搜的遍历过程就是尽可能深的搜索树的分支,当一个节点的所有子节点都被探寻过了,搜索将回溯到发现该节点的那那条边的起始节点
这个过程会一直持续到已发现节点可到达所有节点为止。
如果还存在未发现的节点则进程会随便选择一个未发现的节点重复以上的过程
整个进程直到所有节点都被访问过为止。

深度优先搜索遍历过程
从a开始搜索可以看到a的子节点有c、d、f系统会依次对其进行深度优先搜索
进程先对c进行子节点的搜索可以看出c有两个子节点b、d
可以看出b没有子节点了,但是d节点作为c的子节点还没有被访问所有这个时候程序会走到d的位置
但是d也没有子节点这个时候进程会回溯到发现d的这条边的起始节点a的位置然后在对其进行搜索
a的子节点中只有f没有被遍历了所以进程只能进到f的位置然后在对其进行遍历可以看出f的两个子节点也没有子节点
所以进程在对g、e进行完遍历之后进程结束

广度优先搜索
和深搜不同广搜会沿着树的高度和宽度对节点进行依次遍历
从树的根节点a开始,会发现a的子节点有c、d、f三个子节点,进程会先对这三个节点进行访问然后再访问其的子节点
对c、d、f完成访问之后进行则会探寻这三个节点的子节点并对其进行遍历,可以从图中看出他们的子节点有c、g、e
可以看出c、g、e没有子节点了所以程序对其遍历之后随之结束

深搜代码
public class dfs {
    // 构造图的边
    private int[][] edges = { 
    		{0,0,1,1,0,1,0},
			{0,0,1,0,0,0,0},
			{1,1,0,1,0,0,0},
			{1,0,1,0,0,0,0},
			{0,0,0,0,0,0,1},
			{1,0,0,0,0,0,1},
			{0,0,0,0,1,1,0}
            };
    // 构造图的顶点
    private String[] vertexs = { "a", "b", "c", "d", "e", "f", "g" };
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    public void DFSTra() {
        verStatus = new boolean[vertexsNum];
        for (int i = 0; i < vertexsNum; i++) {
            if (verStatus[i] == false) {
                DFS(i);
            }
        }
    }
    // 递归深搜
    private void DFS(int i) {
        System.out.print(vertexs[i] + " ");
        verStatus[i] = true;
        //深度搜索子节点
        for (int j = firstAdjVex(i); j >= 0; j = nextAdjvex(i, j)) {
            if (!verStatus[j]) {
                DFS(j);
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjVex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] == 1) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String[] args) {
        new dfs().DFSTra();
    }

}



广搜代码
import java.util.LinkedList;
import java.util.Queue;

public class bfs {
	 // 构造图的边
    private int[][] edges = { 
    		{0,0,1,1,0,1,0},
			{0,0,1,0,0,0,0},
			{1,1,0,1,0,0,0},
			{1,0,1,0,0,0,0},
			{0,0,0,0,0,0,1},
			{1,0,0,0,0,0,1},
			{0,0,0,0,1,1,0}
            };
    // 构造图的顶点
    private String[] vertexs = { "a", "b", "c", "d", "e", "f", "g" };
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    // 广搜
    private void BFS() {
        verStatus = new boolean[vertexsNum];
        Queue<Integer> temp = new LinkedList<Integer>();
        //遍历每个节点
        for (int i = 0; i < vertexsNum; i++) {
        	//判断当前节点是否被访问过
            if (!verStatus[i]) {//如果没有被访问的话则将其加入队列
                System.out.print(vertexs[i] + " ");
                verStatus[i] = true;
                temp.offer(i);
                while (!temp.isEmpty()) {
                	//将最先进入队列的节点移除
                    int j = temp.poll();
                    //广度搜索子节点
                    for (int k = firstAdjvex(j); k >= 0; k = nextAdjvex(j, k)) {
                        if (!verStatus[k]) {
                            System.out.print(vertexs[k] + " ");
                            verStatus[k] = true;
                            temp.offer(k);
                        }
                    }
                }
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjvex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String args[]) {
        new bfs().BFS();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136

题目2

在这里插入图片描述
static int[][] nums = {
{ 0 , 1 , 0 , 0 , 0 , 0 , 0, 1 , 0},
{ 1 , 0, 1 ,0 , 1 , 0 , 0 , 0 , 0},
{ 0 , 1 , 0 , 1 , 0 ,0 , 0 , 0 , 0},
{ 0 , 0 , 1 , 0 , 1 , 1 , 0 , 0 ,0},
{ 0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0},
{ 0 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 0},
{ 0 , 0 , 0 , 0 , 0 , 1, 0 , 0 , 0},
{ 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1},
{ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0}
};

static String res[] = {“1”,“2”,“3”,“4”,“5”,“6”,“7”,“8”,“9” };
对此二维数组进行深度搜索与广度搜索,并遍历结果。

深搜结果
1 2 3 4 5 6 7 8 9
广搜结果
1 2 8 3 5 6 9 4 7

深搜的遍历过程就是尽可能深的搜索树的分支,当一个节点的所有子节点都被探寻过了,搜索将回溯到发现该节点的那那条边的起始节点
这个过程会一直持续到已发现节点可到达所有节点为止。
如果还存在未发现的节点则进程会随便选择一个未发现的节点重复以上的过程
整个进程直到所有节点都被访问过为止。

深搜遍历过程
从1开始搜索可以看到1的子节点有2、8两个,进程会依次对其进行深度优先搜索
进程先对2进行子节点的搜索可以看出2也有两个子节点3、5
然后进程又会对3进行子节点的搜索可以看出只有一个子节点4,而4没有子节点了这个时候进程就会回溯到2的位置然后对5进行子节点的搜索
可以看出5的子节点也是只有一个4,但是这个时候5还有一个父节点6没有被访问所以进程不会回溯到2的位置
而是对6进行子节点的搜索,6的子节点只有一个7这个时候进程又会发现6有父节点8没有访问过
所以进程会对8再次再次进行子节点的搜索,发现子节点只有6和9但是6已经访问过了,而9也没有子节点
到这里树的所有节点就完成了全部的探索了

广搜遍历过程
和深搜不同广搜会沿着树的高度和宽度对节点进行依次遍历
从树的根节点1开始,会发现1的子节点有2、8两个子节点,进程会先对这两个节点进行访问然后再访问其的子节点
对2、8完成访问之后进行则会探寻这两个节点的子节点并对其进行遍历,可以从图中看出他们的子节点有3、5、6、9
然后进程对着4个节点完成遍历之后会再次探寻其的子节点可以看出只有4和7了且无子节点
在对4和7完成遍历之后整个进程也就随之结束了

深搜代码
public class dfs {
    // 构造图的边
    private int[][] edges = { 
    		{  0 , 1 , 0 , 0 , 0 , 0 , 0,  1 , 0},
    		{  1 , 0,  1  ,0 , 1 , 0 , 0 , 0 , 0},
    		{  0 , 1 , 0 , 1 , 0  ,0 , 0 , 0 , 0},
    		{  0 , 0 , 1 , 0 , 1 , 1 , 0 , 0  ,0},
    		{  0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0},
    		{  0 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 0},
    		{  0 , 0 , 0 , 0 , 0 , 1,  0 , 0 , 0},
    		{  1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1},
    		{  0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0}
            };
    // 构造图的顶点
    private String[] vertexs = {"1","2","3","4","5","6","7","8","9"};
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    public void DFSTra() {
        verStatus = new boolean[vertexsNum];
        for (int i = 0; i < vertexsNum; i++) {
            if (verStatus[i] == false) {
                DFS(i);
            }
        }
    }
    // 递归深搜
    private void DFS(int i) {
        System.out.print(vertexs[i] + " ");
        verStatus[i] = true;
        //深度搜索子节点
        for (int j = firstAdjVex(i); j >= 0; j = nextAdjvex(i, j)) {
            if (!verStatus[j]) {
                DFS(j);
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjVex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] == 1) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String[] args) {
        new dfs().DFSTra();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
广搜代码
import java.util.LinkedList;
import java.util.Queue;

public class bfs {
    // 构造图的边
    private int[][] edges = { 
    		{  0 , 1 , 0 , 0 , 0 , 0 , 0,  1 , 0},
    		{  1 , 0,  1  ,0 , 1 , 0 , 0 , 0 , 0},
    		{  0 , 1 , 0 , 1 , 0  ,0 , 0 , 0 , 0},
    		{  0 , 0 , 1 , 0 , 1 , 1 , 0 , 0  ,0},
    		{  0 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0},
    		{  0 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 0},
    		{  0 , 0 , 0 , 0 , 0 , 1,  0 , 0 , 0},
    		{  1 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 1},
    		{  0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0}
            };
    // 构造图的顶点
    private String[] vertexs = {"1","2","3","4","5","6","7","8","9"};
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    // 广搜
    private void BFS() {
        verStatus = new boolean[vertexsNum];
        Queue<Integer> temp = new LinkedList<Integer>();
        //遍历每个节点
        for (int i = 0; i < vertexsNum; i++) {
        	//判断当前节点是否被访问过
            if (!verStatus[i]) {//如果没有被访问的话则将其加入队列
                System.out.print(vertexs[i] + " ");
                verStatus[i] = true;
                temp.offer(i);
                while (!temp.isEmpty()) {
                	//将最先进入队列的节点移除
                    int j = temp.poll();
                    //广度搜索子节点
                    for (int k = firstAdjvex(j); k >= 0; k = nextAdjvex(j, k)) {
                        if (!verStatus[k]) {
                            System.out.print(vertexs[k] + " ");
                            verStatus[k] = true;
                            temp.offer(k);
                        }
                    }
                }
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjvex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String args[]) {
        new bfs().BFS();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73

题目3

在这里插入图片描述
static int[][] nums = {
{ 0 , 1 , 1 , 1 , 0 , 0 , 0},
{ 1 , 0 , 1 , 0 , 0 , 1 , 0},
{ 1 , 1 , 0 , 1 , 1 , 0 , 0},
{ 1 , 0 , 1 , 0 , 0 , 0 , 1},
{ 0 , 0 , 1 , 0 , 0 , 0 , 0},
{ 0 , 1 , 0 , 0 , 0 , 0 , 1},
{ 0 , 0 , 0 , 1 , 0 , 1 , 0},
};

static String res[] = { “v1”, “v2”, “v3”, “v4”, “v5”, “v6”, “v7” };
对此二维数组进行深度搜索与广度搜索,并遍历结果。

深搜结果
v1 v2 v3 v4 v7 v6 v5
广搜结果
v1 v2 v3 v4 v6 v5 v7

深搜的遍历过程就是尽可能深的搜索树的分支,当一个节点的所有子节点都被探寻过了,搜索将回溯到发现该节点的那那条边的起始节点
这个过程会一直持续到已发现节点可到达所有节点为止。
如果还存在未发现的节点则进程会随便选择一个未发现的节点重复以上的过程
整个进程直到所有节点都被访问过为止。

深搜遍历过程
从v1开始搜索可以看到a的子节点有v2、v3、v4系统会依次对其进行深度优先搜索
进程先对v2进行子节点的搜索可以看出v2有两个子节点v3、v4
进程会先对v3进行遍历会发现v3的子节点只有v4,然后v4只有一个子节点v7
进程遍历到v7的时候因为v7还有一个父节点v6没有被访问所以进程会走到v6的位置因为v6的根节点已经遍历了
所以进程会返回到发现v6这条边的起始点也就是v1,但是这个时候还有节点没有被遍历所以
进程会随便选择一个未发现的节点进入然后遍历从图中看出只有v5没有遍历了所以
对v5进行遍历之后进程也就随之结束了

广搜遍历过程
和深搜不同广搜会沿着树的高度和宽度对节点进行依次遍历
从树的根节点v1开始,会发现v1的子节点有v2、v3、v4三个子节点,进程会先对这三个节点进行访问然后再遍历其的子节点
对v2、v3、v4完成访问之后则会探寻这三个节点的子节点并对其进行遍历,可以从图中看出他们未访问的子节点只有v6、v5、v7
而v6、v7、v5没有子节点了所以程序对其遍历之后随之结束

深搜代码
public class dfs {
	private int[][] edges = { 
		    { 0  , 1  , 1 , 1 ,  0  , 0  , 0},
			{  1 ,  0  , 1  , 0  , 0 ,  1 ,  0},
			{   1 ,  1  , 0  , 1  , 1 ,  0  , 0},
			{   1 ,  0  , 1 ,  0 ,  0  , 0 ,  1},
			{   0  , 0  , 1 ,  0 ,  0 ,  0 ,  0},
			{   0 ,  1 ,  0  , 0 ,  0 ,  0  , 1},
			{   0  , 0  , 0 ,  1 ,  0  , 1 ,  0},
        };
// 构造图的顶点
private String[] vertexs = {"v1", "v2", "v3", "v4", "v5", "v6", "v7"};
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    public void DFSTra() {
        verStatus = new boolean[vertexsNum];
        for (int i = 0; i < vertexsNum; i++) {
            if (verStatus[i] == false) {
                DFS(i);
            }
        }
    }
    // 递归深搜
    private void DFS(int i) {
        System.out.print(vertexs[i] + " ");
        verStatus[i] = true;
        //深度搜索子节点
        for (int j = firstAdjVex(i); j >= 0; j = nextAdjvex(i, j)) {
            if (!verStatus[j]) {
                DFS(j);
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjVex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] == 1) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String[] args) {
        new dfs().DFSTra();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
广搜代码
public class bfs {
	 // 构造图的边
    private int[][] edges = { 
    		    { 0  , 1  , 1 , 1 ,  0  , 0  , 0},
    			{  1 ,  0  , 1  , 0  , 0 ,  1 ,  0},
    			{   1 ,  1  , 0  , 1  , 1 ,  0  , 0},
    			{   1 ,  0  , 1 ,  0 ,  0  , 0 ,  1},
    			{   0  , 0  , 1 ,  0 ,  0 ,  0 ,  0},
    			{   0 ,  1 ,  0  , 0 ,  0 ,  0  , 1},
    			{   0  , 0  , 0 ,  1 ,  0  , 1 ,  0},
            };
    // 构造图的顶点
    private String[] vertexs = {"v1", "v2", "v3", "v4", "v5", "v6", "v7"};
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    // 广搜
    private void BFS() {
        verStatus = new boolean[vertexsNum];
        Queue<Integer> temp = new LinkedList<Integer>();
        //遍历每个节点
        for (int i = 0; i < vertexsNum; i++) {
        	//判断当前节点是否被访问过
            if (!verStatus[i]) {//如果没有被访问的话则将其加入队列
                System.out.print(vertexs[i] + " ");
                verStatus[i] = true;
                temp.offer(i);
                while (!temp.isEmpty()) {
                	//将最先进入队列的节点移除
                    int j = temp.poll();
                    //广度搜索子节点
                    for (int k = firstAdjvex(j); k >= 0; k = nextAdjvex(j, k)) {
                        if (!verStatus[k]) {
                            System.out.print(vertexs[k] + " ");
                            verStatus[k] = true;
                            temp.offer(k);
                        }
                    }
                }
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjvex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String args[]) {
        new bfs().BFS();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

题目4

在这里插入图片描述
static int[][] nums = {
{ 0 , 1 , 1 , 0 ,0 ,0},
{ 1 , 0 ,1 , 1 ,0, 0},
{ 1 , 1 , 0 ,1 , 1 , 0},
{ 0 , 1 , 1 , 0 , 1 , 1},
{ 0 , 0 , 1 , 1 , 0 , 0},
{ 0 , 0 , 0 , 1 , 0 , 0},
};

static String res[] = { “a”, “b”, “c”, “d”, “e”, “f”};
对此二维数组进行深度搜索与广度搜索,并遍历结果。

深搜结果
a b c d e f
广搜结果
a b c d e f

深搜的遍历过程就是尽可能深的搜索树的分支,当一个节点的所有子节点都被探寻过了,搜索将回溯到发现该节点的那那条边的起始节点
这个过程会一直持续到已发现节点可到达所有节点为止。
如果还存在未发现的节点则进程会随便选择一个未发现的节点重复以上的过程
整个进程直到所有节点都被访问过为止。

深搜遍历过程
从a开始搜索可以看到1的子节点有b、c两个,进程会依次对其进行深度优先搜索
进程先对b进行子节点的搜索可以看出b也有两个子节点c、d
然后进程又会对c进行子节点的搜索可以看出它也是有两个子节点d、e
进程又会查找d的子节点可以发现d也有两个子节点e、f
这个时候e和f都没有子节点了树的所有节点也都被遍历了

广搜遍历过程
和深搜不同广搜会沿着树的高度和宽度对节点进行依次遍历
从树的根节点a开始,会发现a的子节点有b、c两个子节点,进程会先对这两个节点进行访问然后再访问其的子节点
对b、c完成遍历之后进行则会探寻这两个节点的子节点并对其进行遍历,可以从图中看出他们未遍历的子节点有d、e
然后进程对着2个节点完成遍历之后会再次探寻其的子节点
可以看出只有一个f了且f没有子节点所以程序对f完成遍历之后整个进程也就随之结束了

深搜代码
public class dfs {
	 // 构造图的边
    private int[][] edges = { 
    		{ 0 , 1 , 1 , 0  ,0  ,0},
 			{  1 , 0  ,1 , 1  ,0,  0},
 			{  1 , 1 , 0  ,1 , 1 , 0},
 			{  0 , 1 , 1 , 0 , 1 , 1},
 			{  0 , 0 , 1 , 1 , 0 , 0},
 			{  0 , 0 , 0 , 1 , 0 , 0},
            };
    // 构造图的顶点
    private String[] vertexs = { "a", "b", "c", "d", "e", "f"};
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    public void DFSTra() {
        verStatus = new boolean[vertexsNum];
        for (int i = 0; i < vertexsNum; i++) {
            if (verStatus[i] == false) {
                DFS(i);
            }
        }
    }
    // 递归深搜
    private void DFS(int i) {
        System.out.print(vertexs[i] + " ");
        verStatus[i] = true;
        //深度搜索子节点
        for (int j = firstAdjVex(i); j >= 0; j = nextAdjvex(i, j)) {
            if (!verStatus[j]) {
                DFS(j);
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjVex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] == 1) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String[] args) {
        new dfs().DFSTra();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

广搜代码

import java.util.LinkedList;
import java.util.Queue;

public class bfs {
	 // 构造图的边
    private int[][] edges = { 
    		{ 0 , 1 , 1 , 0  ,0  ,0},
 			{  1 , 0  ,1 , 1  ,0,  0},
 			{  1 , 1 , 0  ,1 , 1 , 0},
 			{  0 , 1 , 1 , 0 , 1 , 1},
 			{  0 , 0 , 1 , 1 , 0 , 0},
 			{  0 , 0 , 0 , 1 , 0 , 0},
            };
    // 构造图的顶点
    private String[] vertexs = { "a", "b", "c", "d", "e", "f"};
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    // 广搜
    private void BFS() {
        verStatus = new boolean[vertexsNum];
        Queue<Integer> temp = new LinkedList<Integer>();
        //遍历每个节点
        for (int i = 0; i < vertexsNum; i++) {
        	//判断当前节点是否被访问过
            if (!verStatus[i]) {//如果没有被访问的话则将其加入队列
                System.out.print(vertexs[i] + " ");
                verStatus[i] = true;
                temp.offer(i);
                while (!temp.isEmpty()) {
                	//将最先进入队列的节点移除
                    int j = temp.poll();
                    //广度搜索子节点
                    for (int k = firstAdjvex(j); k >= 0; k = nextAdjvex(j, k)) {
                        if (!verStatus[k]) {
                            System.out.print(vertexs[k] + " ");
                            verStatus[k] = true;
                            temp.offer(k);
                        }
                    }
                }
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjvex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String args[]) {
        new bfs().BFS();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

题目5

在这里插入图片描述
static int[][] nums = {
{ 0 , 1 , 0 , 0 , 1 ,1},
{ 1 , 0 , 1, 1 , 0 , 1},
{ 0 , 1 , 0 , 1 , 0, 0},
{ 0 , 1 , 1, 0 , 1 , 1},
{ 1 , 0 , 0 , 1 , 0 , 1},
{ 1 , 1 , 0 , 1 , 1 , 0},
};

static String res[] = { “a”, “b”, “c”, “d”, “e”, “f”};
对此二维数组进行深度搜索与广度搜索,并遍历结果。

深搜结果
a b c d e f
广搜结果
a b e f c d

深搜的遍历过程就是尽可能深的搜索树的分支,当一个节点的所有子节点都被探寻过了,搜索将回溯到发现该节点的那那条边的起始节点
这个过程会一直持续到已发现节点可到达所有节点为止。
如果还存在未发现的节点则进程会随便选择一个未发现的节点重复以上的过程
整个进程直到所有节点都被访问过为止。

深度优先搜索遍历过程
从a开始搜索可以看到a的子节点有b、e、f三个进程会依次对其进行深度优先搜索
进程先对b进行子节点的搜索可以看出b也有三个子节点c、d、f
然后进程对c进行子节点的搜索可以从图中看出c的子节点只有d,在对d进行完遍历之后
d虽然没有子节点但是它还有一个没有被遍历的父节点e所以这个时候进程会走到e
e的子节点有d、f两个但是d已经被遍历了所以现在只能遍历f了
在对f完成遍历之后整个树的节点也就全部都遍历完成了

广度优先搜索
和深搜不同广搜会沿着树的高度和宽度对节点进行依次遍历
从树的根节点a开始,会发现a的子节点有b、e、f三个子节点,进程会先对这三个节点进行访问然后再访问其的子节点
对b、e、f完成访问之后进行则会探寻这三个节点的子节点并对其进行遍历,可以从图中看出他们未遍历的子节点只有c、d了
而对c、d完成遍历之后他们也就没有子节点可以遍历了所以整个程序也就结束了

深搜代码

public class dfs {
	 // 构造图的边
    private int[][] edges = { 
    		{  0 , 1 , 0 , 0 , 1  ,1},
 			{  1 , 0 , 1,  1 , 0 , 1},
 			{  0 , 1 , 0 , 1 , 0,  0},
 			{  0 , 1 , 1,  0 , 1 , 1},
 			{  1 , 0 , 0 , 1 , 0 , 1},
 			{  1 , 1 , 0 , 1 , 1 , 0},
            };
    // 构造图的顶点
    private String[] vertexs = { "a", "b", "c", "d", "e", "f"};
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    public void DFSTra() {
        verStatus = new boolean[vertexsNum];
        for (int i = 0; i < vertexsNum; i++) {
            if (verStatus[i] == false) {
                DFS(i);
            }
        }
    }
    // 递归深搜
    private void DFS(int i) {
        System.out.print(vertexs[i] + " ");
        verStatus[i] = true;
        //深度搜索子节点
        for (int j = firstAdjVex(i); j >= 0; j = nextAdjvex(i, j)) {
            if (!verStatus[j]) {
                DFS(j);
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjVex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] == 1) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String[] args) {
        new dfs().DFSTra();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

广搜代码

import java.util.LinkedList;
import java.util.Queue;

public class bfs {
	 // 构造图的边
    private int[][] edges = { 
    		{  0 , 1 , 0 , 0 , 1  ,1},
 			{  1 , 0 , 1,  1 , 0 , 1},
 			{  0 , 1 , 0 , 1 , 0,  0},
 			{  0 , 1 , 1,  0 , 1 , 1},
 			{  1 , 0 , 0 , 1 , 0 , 1},
 			{  1 , 1 , 0 , 1 , 1 , 0},
            };
    // 构造图的顶点
    private String[] vertexs = { "a", "b", "c", "d", "e", "f"};
    // 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
    // 广搜
    private void BFS() {
        verStatus = new boolean[vertexsNum];
        Queue<Integer> temp = new LinkedList<Integer>();
        //遍历每个节点
        for (int i = 0; i < vertexsNum; i++) {
        	//判断当前节点是否被访问过
            if (!verStatus[i]) {//如果没有被访问的话则将其加入队列
                System.out.print(vertexs[i] + " ");
                verStatus[i] = true;
                temp.offer(i);
                while (!temp.isEmpty()) {
                	//将最先进入队列的节点移除
                    int j = temp.poll();
                    //广度搜索子节点
                    for (int k = firstAdjvex(j); k >= 0; k = nextAdjvex(j, k)) {
                        if (!verStatus[k]) {
                            System.out.print(vertexs[k] + " ");
                            verStatus[k] = true;
                            temp.offer(k);
                        }
                    }
                }
            }
        }
    }
    // 返回与i相连的第一个顶点
    private int firstAdjvex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }

    // 测试
    public static void main(String args[]) {
        new bfs().BFS();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/434458
推荐阅读
相关标签
  

闽ICP备14008679号