We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
本文将针对二叉树中几种常见的遍历方法进行介绍。
前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树。
中序遍历是先遍历左子树,然后访问根节点,然后遍历右子树。
后序遍历是先遍历左子树,然后遍历右子树,最后访问树的根节点。
递归实现二叉树的遍历是非常简单的,其核心就是 深度优先搜索(DFS) 算法。
由于比较简单,三种遍历方式的实现代码只是 深度优先搜索 过程中执行顺序的区别,故模版如下:
public class Solution { // 递归遍历二叉树 public List<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); if (root == null) return list; dfs(root, list); return list; } private void dfs(TreeNode root, ArrayList<Integer> list) { if (root == null) return; // 前序遍历 根 -> 左 -> 右 list.add(root.val); // 根 dfs(root.left, list); // 左 dfs(root.right, list); // 右 // 中序遍历 右 -> 根 -> 右 // dfs(root.left, list); // list.add(root.val); // dfs(root.right, list); // 后序遍历 左 -> 右 -> 根 // dfs(node.left, list); // dfs(node.right, list); // list.add(node.val); } }
通过迭代对前序遍历需要一个栈进行辅助,其负责对不同层级父子节点进行迭代存储。
class Solution { public List<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode curr = root; // 1.退出最外层迭代的条件是,指针指向null,且栈为空 while (curr != null || !stack.isEmpty()) { // 2.内层循环按顺序入栈,同时更新当前指针 // 4.这时候也可能是开始遍历右节点 while (curr != null) { stack.push(curr); list.add(curr.val); curr = curr.left; } // 3.返回父节点,并将指针指向右节点 curr = stack.pop(); curr = curr.right; } return list; } }
中序遍历和前序遍历思想是一致的,区别仅仅在于根节点在左叶子节点添加之后添加:
class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode curr = root; // 1.退出最外层迭代的条件是,指针指向null,且栈为空 while (!stack.isEmpty() || curr != null) { // 2.内层循环按顺序入栈,同时更新当前指针 // 5.这时候也可能是开始遍历右节点 while (curr != null) { stack.push(curr.left); curr = curr.left; } // 3.返回父节点,并加入数组中 curr = stack.pop(); list.add(curr.val); // 4.将指针指向右节点 curr = curr.right; } return list; } }
后序遍历 LeetCode 官方题解给出了一个额外的思路,对于树的 后序遍历 而言,其遍历顺序与 广度优先搜索(BFS) 恰恰是相反的:
LeetCode
如图所示,BFS的遍历顺序是 1->2->3->4->5,而相同的树后序遍历顺序则是 4->5->2->3->1。
BFS
1->2->3->4->5
4->5->2->3->1
因此,后序遍历的思路如下:
从根节点开始依次迭代,弹出栈顶元素输出到输出列表中,然后依次压入它的所有孩子节点,按照从上到下、从左至右的顺序依次压入栈中。
因为深度优先搜索后序遍历的顺序是从下到上、从左至右,所以需要将输出列表逆序输出。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List<Integer> postorderTraversal(TreeNode root) { LinkedList<Integer> output = new LinkedList<>(); // 和传统的bfs不同,这里并没有用 Queue // 因为顺序是相反的,这里并不是取第一个元素,而是取栈顶的元素(即同层级节点从右->左遍历) Stack<TreeNode> stack = new Stack<>(); if (root == null) return output; stack.push(root); while(!stack.isEmpty()) { TreeNode node = stack.pop(); output.addFirst(node.val); if (node.left != null) { stack.push(node.left); } if (node.right != null) { stack.push(node.right); } } return output; } }
文章绝大部分内容节选自LeetCode,概述:
例题:
Hello,我是 却把清梅嗅 ,如果您觉得文章对您有价值,欢迎 ❤️,也欢迎关注我的 博客 或者 GitHub。
如果您觉得文章还差了那么点东西,也请通过关注督促我写出更好的文章——万一哪天我进步了呢?
The text was updated successfully, but these errors were encountered:
No branches or pull requests
二叉树的递归与迭代遍历
本文将针对二叉树中几种常见的遍历方法进行介绍。
遍历方式
前序遍历
前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树。
中序遍历
中序遍历是先遍历左子树,然后访问根节点,然后遍历右子树。
后序遍历
后序遍历是先遍历左子树,然后遍历右子树,最后访问树的根节点。
递归实现
递归实现二叉树的遍历是非常简单的,其核心就是 深度优先搜索(DFS) 算法。
由于比较简单,三种遍历方式的实现代码只是 深度优先搜索 过程中执行顺序的区别,故模版如下:
迭代实现
前序遍历
通过迭代对前序遍历需要一个栈进行辅助,其负责对不同层级父子节点进行迭代存储。
中序遍历
中序遍历和前序遍历思想是一致的,区别仅仅在于根节点在左叶子节点添加之后添加:
后序遍历
后序遍历
LeetCode
官方题解给出了一个额外的思路,对于树的 后序遍历 而言,其遍历顺序与 广度优先搜索(BFS) 恰恰是相反的:如图所示,
BFS
的遍历顺序是1->2->3->4->5
,而相同的树后序遍历顺序则是4->5->2->3->1
。因此,后序遍历的思路如下:
参考 & 感谢
文章绝大部分内容节选自
LeetCode
,概述:例题:
关于我
Hello,我是 却把清梅嗅 ,如果您觉得文章对您有价值,欢迎 ❤️,也欢迎关注我的 博客 或者 GitHub。
如果您觉得文章还差了那么点东西,也请通过关注督促我写出更好的文章——万一哪天我进步了呢?
The text was updated successfully, but these errors were encountered: