多叉树的前序遍历_【算法】二叉树、N叉树先序、中序、后序、BFS、DFS遍历的递归和迭代实现记录(Java版)...

本文总结了刷LeetCode过程中,有关树的遍历的相关代码实现,包括了二叉树、N叉树先序、中序、后序、BFS、DFS遍历的递归和迭代实现。这也是解决树的遍历问题的固定套路。

一、二叉树的先序、中序、后序遍历

1、递归模板

(1)先序

1 public voidpreorder(TreeNode root) {2 if (root == null) {3 return;4 }5 res.add(root.val);6 preorder(root.left);7 preorder(root.right);8 }

(2)中序

inorder(TreeNode root) {3 inorder(root.left);inorder(root.right);8 }

(3)后序

postorder(TreeNode root) {2 }postorder(root.left);postorder(root.right);res.add(root.val);8 }

2、迭代模板:显式使用栈

(1)先序 。也可以使用后文的DFS实现

1 2 Deque stack = new ArrayDeque<>();3 while(root !=null || !stack.isEmpty()) {4 while(root != 5 stack.push(root);6 res.add(root.val);//保存结果

7 root =root.left;8 }9 root =stack.pop();10 root =root.right;11 }12 }

(2)中序

2 Deque stack = 3 4 stack.push(root);6 root =7 }8 root =9 res.add(root.val);10 root =12 }

(3)后序。先序是根——左——右,而后序是左-右-根,可以将先序改成根-右-左,然后将结果反转。如下代码对比先序的代码:

3 7 root = root.right;注意这里和先序、中序的差别

root.left();}12 Collections.reverse(res);将前面的结果反转

13 }

当然,上面这种方法比较间接,借助于先序遍历的理解。下面采用一种直接的迭代方式:

3 TreeNode preNode = new TreeNode();该节点用于保存前一个出栈的节点

4 while (root != 5 将当前节点的左子树节点一次入栈

6 8 root =9 }10 root =stack.peek();11 当前节点没有右孩子了,或者其右孩子已经出栈了,则当前节点也出栈

12 if (root.right == null || root.right ==preNode) {13 root =14 res.add(root.val);15 preNode = root; 记录本次刚输出的节点

16 root = 17 } else{18 当前节点还有右孩子,且其右孩子还没有出栈,则先处理其右孩子

19 root =20 21 22 }

二、N叉树的先序与后序遍历

1、递归模板

(1)先序

2 3 4 5 res.add(root.val);6 if (root.children != 7 for (int i = 0; i < root.children.size(); i++dfs(root.children.get(i));10 11 }

(2)后序

3 5 postorder(root.children.get(i));8 res.add(root.val);9 }

2、迭代模板

(1)先序。即下文中DFS的实现

preorder(Node root) {2 Deque stack = new ArrayDeque<>(); BFS使用队列,这里使用栈

3 stack.push(root);4 while (!5 root =6 res.add(root.val);7 int childCount = root.children == null ? 0: root.children.size();8 这里需要注意孩子节点入栈的顺序

9 int i = childCount - 1; i >= 0; i--stack.push(root.children.get(i));12 13 }

(2)后序。先序是根——左——右,而后序是左-右-根,可以将先序改成根-右-左,然后将结果反转。如下代码对比先序的代码:

postorder(Node root) {2 List result = new ArrayList<>3 Deque stack = 5 6 root =7 result.add(root.val);还入栈的顺序正好和先序遍历相反

10 int i = 0; i < childCount; i++13 14 将结果反转

15 Collections.reverse(result);16 for(Integer i:result) {17 System.out.print(i);18 19 }

目前还没有找到类似二叉树直接后序遍历的方法

三、树的BFS(广度优先搜索)和DFS(深度优先搜索)实现模板

1、递归实现

(1)BFS

一般来说不能使用递归来实现BFS,因为BFS使用的时队列实现,而递归使用的是栈实现。

(2)DFS

普通的N叉树的DFS包括先序遍历和后序遍历,它们的递归实现和前文一致。如果是二叉树,还有中序遍历,递归实现和前文一致。

2、迭代实现

(1)BFS。即按层次来遍历

bfs(Node root) {2 Queue queue = new LinkedList<>queue.offer(root);queue.isEmpty()) {queue.poll();queue.addAll(root.children);//这里的addAll后,root的children会从左往右依次入队。这一点Deque实现的栈正好相反,这一点需要注意11 }

(2)DFS

先序遍历、中序遍历(二叉树)和后序遍历的迭代方式实现和前文一致。

四、图的BFS和DFS遍历模板

树是图的一种特殊情况,相比于树而言图中可能出现环,所以在遍历的时候可能重复访问。所以树的BFS和DFS实现需要在树的基础上维护一个Set来避免访问重复的节点即可。

1、BFS

graphyBfs(Node root) {5 Set visitedSet = new HashSet<>(); 维护一个set,保存已经访问过的节点

6 Queue queue = queue.offer(root);8 9 root =10 visitedSet.add(root);保存每个已经输出的节点

11 res.add(root.val);if (root.children == 13 14 15 16 Node tmpNode =root.children.get(i);17 if (!visitedSet.contains(tmpNode)) {已经输出过的节点,则不用再加入

queue.offer(tmpNode);19 }22 }

2、DFS

迭代方式、递归方式,都维护一个set来保存已经访问过的节点,在输出节点时保存到set中,在添加节点时添加去重操作即可。

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值