1. 四种遍历方式
前中后序遍历相当于图论中的DFS(深度优先搜索)
层序遍历相当于图论中的BFS(广度优先搜索)
(1)前序遍历
根节点->左子树->右子树
(2)中序遍历
左子树->根节点->右子树
(3) 后序遍历
左子树->右子树->根节点
(4)层序遍历
每一层进行遍历
1.1. 力扣实现(java版)
1.1.1 (94)二叉树的中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
inorder(root, result);
return result;
}
private void inorder(TreeNode node, List<Integer> result) {
if (node == null) return;
inorder(node.left, result); // 递归左子树
result.add(node.val); // 访问根节点
inorder(node.right, result); // 递归右子树
}
}
1.1.2 (144)二叉树的前序遍历
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
preorder(root,res);
return res;
}
public void preorder(TreeNode root, List<Integer> res){
if(root == null) return;
res.add(root.val);
preorder(root.left,res);
preorder(root.right,res);
}
}
1.1.3 (144)二叉树的后序遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
postorder(root , res);
return res;
}
public void postorder(TreeNode root,List<Integer> res){
if(root == null) return;
postorder(root.left,res);
postorder(root.right,res);
res.add(root.val);
}
}
前面三种遍历方式使用迭代的方法,模板很固定,到根节点打印就行了。
1.1.4 (102)二叉树的层序遍历
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
//注意点1
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if(root != null) queue.add(root);
while(!queue.isEmpty()){
List<Integer> tmp = new ArrayList<>();
//注意点2
for(int i = queue.size();i > 0;i--){
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
res.add(tmp);
}
return res;
}
}
对于层序遍历,需要重点注意一下两个地方:
1. 如何存储每一层的结点数值?
对于二叉树这种数据结构,无法直接存储每一层的结点数值,只能进行DFS,因此需要换一种新的数据结构来存储-------队列,在java中通常使用LinkedList,实现了 Deque 接口(双向队列),而 Deque 继承自 Queue。
而下面对输出结果res使用的是ArrayList,具有访问快,顺序好的特点。
对这两种具体实现类需要有所了解。
2.queue.size()是动态变化的
在把每一层的结点数值存储到tmp中的时候,使用的for循环如下所示:
for(int i = queue.size();i > 0;i--)
而不是我们经常使用的
for(int i = 0;i < queue.size();i++)
这是因为**queue.size()**是会变化的,问题就出在循环中的
TreeNode node = queue.poll();
这行代码运行后,队列弹出一个结点,会导致queue的长度减少,这样**queue.size()**也就会减少,导致代码出错。
当然如果在循环前保存了queue.size(),也可以从0开始遍历,如下所示。
int size = queue.size();
for(int i = 0;i < queue.size();i++)
2250

被折叠的 条评论
为什么被折叠?



