一、102二叉树的层序遍历
有三个需要注意的点:
- 对根节点非空判断。空节点入队!
if (root != null)
deque.add(root);
- 对每一层的节点数(即下一层开始时队列的大小)进行存储。
int size = deque.size(); //每一层的节点数
List<Integer> tmp = new ArrayList<>(); //每一层节点遍历后存储的list数组
while ((size--) != 0) { //当遍历完该层节点跳出循环
- 需要判断节点的左右孩子是否为空。依旧遵循着空节点不入队的原则。
//需要判断左右子树是否为空,空节点不进队列
if(node.left!=null) deque.add(node.left);
if(node.right!=null) deque.add(node.right);
以下是完整代码部分:
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
Deque<TreeNode> deque = new LinkedList();
if (root != null)
deque.add(root);
while (!deque.isEmpty()) {
int size = deque.size(); //每一层的节点数
List<Integer> tmp = new ArrayList<>(); //每一层节点遍历后存储的list数组
while ((size--) != 0) { //当遍历完该层节点跳出循环
TreeNode node = deque.remove();
tmp.add(node.val);
//需要判断左右子树是否为空,空节点不进队列
if(node.left!=null) deque.add(node.left);
if(node.right!=null) deque.add(node.right);
}
res.add(tmp);
}
return res;
}
二、226翻转二叉树
这道题我是在后序遍历的基础上将处理节点的那行代码修改成交换左右孩子。
以下是代码部分:
public TreeNode invertTree(TreeNode root) {
preorder(root);
return root;
}
private void preorder(TreeNode node){
if(node == null)
return;
preorder(node.left);
preorder(node.right);
//调换顺序
TreeNode tmp = node.left;
node.left = node.right;
node.right = tmp;
}
当然,这道题也可以使用前序遍历和中序遍历,其中中序遍历在完成交换左右孩子后,再访问一次左子树(即没交换以前的右子树)
同时,代码可以直接以给的方法作为递归函数 ,此时就不需要再额外定义一个用于递归的方法。
以下是代码部分:
class Solution {
public:
TreeNode* invertTree(TreeNode* root) {
if (root == NULL) return root;
invertTree(root->left); // 左
swap(root->left, root->right); // 中
invertTree(root->left); // 注意 这里依然要遍历左孩子,因为中间节点已经翻转了
return root;
}
};
三、101对称二叉树
这道题学习到的知识:
- 通过再参数中存放两个节点,可以同时遍历以这两个节点为根节点的子树。
- 终止条件不一定只有一个,可以有很多个。
- 对于对称的比较,分别比较外侧和内测是否都相等。
以下是代码部分:
public class 对称二叉树101 {
public boolean isSymmetric(TreeNode root) {
return commapre(root.left,root.right);
}
private boolean commapre(TreeNode left,TreeNode right){
//终止条件。
if(left!=null && right==null)
return false;
else if(left==null && right!=null)
return false;
else if(left==null && right==null)
return true;
//此时,只剩下node左节点与右节点都不为null的情况
else if(left.val !=right.val)
return false;
else {
//同时遍历两棵树,必须使用后序遍历
boolean out = commapre(left.left,right.right);
boolean in = commapre(left.right,right.left);
return out && in;
}
}
}