爪哇2博客
爪哇2博客

爪哇深度优先搜索

如果您想练习数据结构和算法程序,可以通过 数据结构和算法面试题.


在上一篇文章中,我们已经看到 广度优先搜索(bfs)。在本文中,我们将看到如何在Java中实现深度优先搜索(DFS)。

图遍历算法

在DFS中,从一个未访问的节点开始并开始选择一个相邻节点,直到您别无选择,然后回溯直到您有另一个选择来选择一个节点的机会,否则,您将选择另一个未访问的节点。

DFS可以通过两种方式实现。

  • 递归的
  • 迭代式

迭代式

深度优先搜索可以使用迭代方法来实现。
让我们借助示例进行查看:

深度优先搜索示例

我们从节点40开始。当它们直接连接时,它们分别访问节点20,节点50,节点70。之后,它分别回溯到节点20和拜访了节点60,节点30和节点10。

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
 
//使用堆栈的迭代DFS
上市  虚空 dfsUsingStack(节点 节点)
{
叠放<节点> =  叠放<节点>();
.(节点);
(!.是空的())
{
节点 元件=.流行音乐();
如果(!元件.参观过)
{
系统..打印(元件.数据 + );
元件.参观过=真正;
}
清单<节点> 邻居=元件.得到Neighbours();
对于 (整型 i = 0; i < 邻居.尺寸(); i++) {
节点 n=邻居.得到(i);
如果(n!=空值 && !n.参观过)
{
.(n);
}
}
}
}
 

递归的

深度优先搜索也可以使用递归来实现。我们不需要维护外部堆栈,将通过递归来照顾它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
//递归DFS
上市  虚空 dfs(节点 节点)
{
系统..打印(节点.数据 + );
清单 邻居=节点.得到Neighbours();
        节点.参观过=真正;
对于 (整型 i = 0; i < 邻居.尺寸(); i++) {
节点 n=邻居.得到(i);
如果(n!=空值 && !n.参观过)
{
dfs(n);
}
}
}
 

爪哇 DFS示例

有两种表示图形的方法。

    • 使用邻居列表
    • 使用邻接矩阵

使用邻居列表

在此,您可以拥有列表<Node> as 邻居 in 节点 类 as below.

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
 
静态的 节点
{
整型 数据;
布尔值 参观过;
清单<节点> 邻居;
 
节点(整型 数据)
{
这个.数据=数据;
这个.邻居= 数组列表<>();
 
}
上市 虚空 邻居(节点 邻居节点)
{
这个.邻居.(邻居节点);
}
上市 清单 得到Neighbours() {
返回 邻居;
}
上市 虚空 setNeighbours(清单 邻居) {
这个.邻居 = 邻居;
}
}
 

这是用于DFS实现的完整Java程序,用于迭代和递归方法。

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
 
组织.Arpit.爪哇2blog;
进口 爪哇.实用程序.数组列表;
进口 爪哇.实用程序.清单;
进口 爪哇.实用程序.叠放;
 
上市 DepthFirstSearchExampleNeighbourList
{
 
静态的 节点
{
整型 数据;
布尔值 参观过;
清单<节点> 邻居;
 
节点(整型 数据)
{
这个.数据=数据;
这个.邻居= 数组列表<>();
 
}
上市 虚空 邻居(节点 邻居节点)
{
这个.邻居.(邻居节点);
}
上市 清单<节点> 得到Neighbours() {
返回 邻居;
}
上市 虚空 setNeighbours(清单<节点> 邻居) {
这个.邻居 = 邻居;
}
}
 
//递归DFS
上市  虚空 dfs(节点 节点)
{
系统..打印(节点.数据 + );
清单<节点> 邻居=节点.得到Neighbours();
        节点.参观过=真正;
对于 (整型 i = 0; i < 邻居.尺寸(); i++) {
节点 n=邻居.得到(i);
如果(n!=空值 && !n.参观过)
{
dfs(n);
}
}
}
 
//使用堆栈的迭代DFS
上市  虚空 dfsUsingStack(节点 节点)
{
叠放<节点> =  叠放<节点>();
.(节点);
(!.是空的())
{
节点 元件=.流行音乐();
如果(!元件.参观过)
{
系统..打印(元件.数据 + );
元件.参观过=真正;
}
清单<节点> 邻居=元件.得到Neighbours();
对于 (整型 i = 0; i < 邻居.尺寸(); i++) {
节点 n=邻居.得到(i);
如果(n!=空值 && !n.参观过)
{
.(n);
}
}
}
}
 
上市 静态的 虚空 主要( 精氨酸[])
{
 
节点 节点40 = 节点(40);
节点 节点10 = 节点(10);
节点 节点20 = 节点(20);
节点 节点30 = 节点(30);
节点 节点60 = 节点(60);
节点 节点50 = 节点(50);
节点 节点70 = 节点(70);
 
节点40.邻居(节点10);
节点40.邻居(节点20);
节点10.邻居(节点30);
节点20.邻居(节点10);
节点20.邻居(节点30);
节点20.邻居(节点60);
节点20.邻居(节点50);
节点30.邻居(节点60);
节点60.邻居(节点70);
节点50.邻居(节点70);
 
DepthFirstSearchExampleNeighbourList dfsExample = DepthFirstSearchExampleNeighbourList();
 
系统..打印(“使用堆栈对图进行DFS遍历”);
dfsExample.dfsUsingStack(节点40);
 
系统..打印();
 
//重置节点的访问标志
节点40.参观过=;
节点10.参观过=;
节点20.参观过=;
节点30.参观过=;
节点60.参观过=;
节点50.参观过=;
节点70.参观过=;
 
 
系统..打印(“使用递归对图进行DFS遍历”);
dfsExample.dfs(节点40);
}
}
 

当您在程序上方运行时,将获得以下输出

1
2
3
4
5
6
 
DFS 遍历 图形 使用
40 20 50 70 60 30 10
DFS 遍历 图形 使用 递归
40 10 30 60 70 20 50
 

使用邻接矩阵

Adjacency_matrix用于查找两个节点之间的连接。

如果adjacency_matrix [i] [j] == 1,则索引i和索引j的节点已连接

下图将帮助您了解邻接矩阵。

邻接矩阵

创建DepthFirstSearchExample.java

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
137
138
139
140
141
142
 
组织.Arpit.爪哇2blog.图形;
 
进口 爪哇.实用程序.数组列表;
进口 爪哇.实用程序.叠放;
 
上市 DepthFirstSearchExample
{
 
静态的 数组列表<节点> 节点= 数组列表<>();
静态的 节点
{
整型 数据;
布尔值 参观过;
 
节点(整型 数据)
{
这个.数据=数据;
 
}
}
 
//使用邻接矩阵找到节点的邻居
//如果adjacency_matrix [i] [j] == 1,则索引i和索引j的节点已连接
上市 数组列表<节点> findNeighbours(整型 adjacency_matrix[][],节点 x)
{
整型 节点Index=-1;
 
数组列表<节点> 邻居= 数组列表<>();
对于 (整型 i = 0; i < 节点.尺寸(); i++) {
如果(节点.得到(i).等于(x))
{
节点Index=i;
打破;
}
}
 
如果(节点Index!=-1)
{
对于 (整型 j = 0; j < adjacency_matrix[节点Index].长度; j++) {
如果(adjacency_matrix[节点Index][j]==1)
{
邻居.(节点.得到(j));
}
}
}
返回 邻居;
}
 
 
//递归DFS
上市  虚空 dfs(整型 adjacency_matrix[][], 节点 节点)
{
 
系统..打印(节点.数据 + );
数组列表<节点> 邻居=findNeighbours(adjacency_matrix,节点);
        节点.参观过=真正;
对于 (整型 i = 0; i < 邻居.尺寸(); i++) {
节点 n=邻居.得到(i);
如果(n!=空值 && !n.参观过)
{
dfs(adjacency_matrix,n);
}
}
}
 
    //使用堆栈的迭代DFS
上市  虚空 dfsUsingStack(整型 adjacency_matrix[][], 节点 节点)
{
叠放<节点> =  叠放<>();
.(节点);
 
(!.是空的())
{
节点 元件=.流行音乐();
如果(!元件.参观过)
{
系统..打印(元件.数据 + );
元件.参观过=真正;
}
数组列表<节点> 邻居=findNeighbours(adjacency_matrix,元件);
对于 (整型 i = 0; i < 邻居.尺寸(); i++) {
节点 n=邻居.得到(i);
如果(n!=空值 &&!n.参观过)
{
.(n);
}
}
}
}
 
上市 静态的 虚空 主要( 精氨酸[])
{
 
节点 节点40 = 节点(40);
节点 节点10 = 节点(10);
节点 节点20 = 节点(20);
节点 节点30 = 节点(30);
节点 节点60 = 节点(60);
节点 节点50 = 节点(50);
节点 节点70 = 节点(70);
 
节点.(节点40);
节点.(节点10);
节点.(节点20);
节点.(节点30);
节点.(节点60);
节点.(节点50);
节点.(节点70);
整型 adjacency_matrix[][] = {
{0,1,1,0,0,0,0},  // 节点 1: 40
{0,0,0,1,0,0,0},  // 节点 2 :10
{0,1,0,1,1,1,0},  // 节点 3: 20
{0,0,0,0,1,0,0},  // 节点 4: 30
{0,0,0,0,0,0,1},  // 节点 5: 60
{0,0,0,0,0,0,1},  // 节点 6: 50
{0,0,0,0,0,0,0},  // 节点 7: 70
};
 
DepthFirstSearchExample dfsExample = DepthFirstSearchExample();
 
系统..打印(“使用堆栈对图进行DFS遍历”);
dfsExample.dfsUsingStack(adjacency_matrix, 节点40);
 
系统..打印();
 
clearVisitedFlags();
 
系统..打印(“使用递归对图进行DFS遍历”);
dfsExample.dfs(adjacency_matrix, 节点40);
 
}
 
上市 静态的 虚空 clearVisitedFlags()
{
对于 (整型 i = 0; i < 节点.尺寸(); i++) {
节点.得到(i).参观过=;
}
}
}
 

当您在程序上方运行时,将获得以下输出

1
2
3
4
5
6
 
DFS 遍历 图形 使用
40 20 50 70 60 30 10
DFS 遍历 图形 使用 递归
40 10 30 60 70 20 50
 

请通过 数据结构和算法面试程序 有关更多此类程序。


导入联系人

您可能还喜欢:

分享这个

作者

关注作者

相关文章

Comments

发表评论

您的电子邮件地址不会被公开。 必需的地方已做标记 *

订阅我们的新闻

获取质量教程到您的收件箱。现在订阅。


成为朋友

©2020 爪哇2博客