dfs bfs. java_二叉树的 dfs 和 bfs(java 实现)

二叉树的 dfs

dfs(Depth-First-Search),即深度优先遍历。从根开始,一路往下遍历,遍历到底再返回,找到下一未访问的点,继续往下遍历,直到所有点都遍历完毕。如果是先访问左孩子的话,和前序遍历是一样的。

例如有一棵二叉树如下:

6223ea82b9a0fab69f1b9060e66450d8.png

那么其深度优先遍历的结果为:

[1, 3, 7, 8, 11, 12, 5, 9, 15, 13, 14]

二叉树的 bfs

bfs(Breadth-First-Search),即广度优先遍历。从根开始,一层一层地往下遍历,每一层从左往右遍历,直到遍历完所有的点。也称为层序遍历。

继续用上面那个例子,二叉树如下:

6223ea82b9a0fab69f1b9060e66450d8.png

其广度优先遍历为:

[1, 3, 5, 7, 8, 9, 15, 11, 12, 13, 14]

代码实现

结构定义

首先定义二叉树:1

2

3

4

5

6

7

8

9public class{

int val;

TreeNode left;

TreeNode right;

TreeNode(int x) {

val = x;

}

}

遍历结果存储在一个 list 中:1private List res = new ArrayList<>();

二叉树的 dfs

二叉树的 dfs 可分为递归实现和非递归实现。

首先看递归实现,递归实现比较简单,过程和前序遍历一样,先访问根节点,然后分别递归访问左子树和右子树:1

2

3

4

5

6

7

8

9

10

11

12

13* 深度优先遍历(递归)

*/

private void dfs_recursion(TreeNode root){

if (root == null) {

return;

}

res.add(root.val);

//递归遍历左子树和右子树

dfs_recursion(root.left);

dfs_recursion(root.right);

}

接着看非递归实现,非递归的话需要借助栈,栈用来存右子树,当没有左子树可访问的时候,就从栈中取出最近放入的右子树,具体实现如下:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18* 深度优先遍历(非递归)

*/

private void dfs(TreeNode root){

// 栈用来存储右孩子

Stack stack = new Stack<>();

TreeNode curr = root;

while (curr != null) {

res.add(curr.val);

if (curr.right != null) {

stack.push(curr.right);

}

curr = curr.left;

if (curr == null && !stack.isEmpty()) {

curr = stack.pop();

}

}

}

二叉树的 bfs

二叉树的 bfs 同样可以分为递归和非递归两种实现。和 dfs 相反,bfs 的非递归更容易实现,所以先看非递归。

非递归需要借助队列,利用队列先进先出的性质可以很方便地一层一层遍历元素,实现如下:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20* 广度优先遍历(非递归)

*/

private void bfs(TreeNode root){

// 利用队列先进先出的性质存储节点

LinkedList queue = new LinkedList<>();

if (root != null) {

queue.add(root);

}

while (!queue.isEmpty()) {

TreeNode curr = queue.remove();

res.add(curr.val);

if (curr.left != null) {

queue.add(curr.left);

}

if (curr.right != null) {

queue.add(curr.right);

}

}

}

如果要递归实现的话,要每一层都用一个 list 来记录元素。具体实现如下: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* 广度优先遍历(递归)

*/

private void bfs_recursion(TreeNode root){

// 每一层都要借助一个 List 存储元素

List> bfsRes = new ArrayList<>();

find(bfsRes, 0, root);

for (int i = 0; i < bfsRes.size(); i++) {

List curr = bfsRes.get(i);

res.addAll(curr);

}

}

* 将第 level 层的 node 节点放入 res 的第 level 个集合中

*/

private void find(List> res, int level, TreeNode node){

if (node == null) {

return;

}

if (res.size() <= level) {

List list = new ArrayList<>();

list.add(node.val);

res.add(list);

} else {

List list = res.get(level);

list.add(node.val);

}

find(res, level+1, node.left);

find(res, level+1, node.right);

}

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值