二叉树在算法中也是比较常用的数据结构,根据二叉树的遍历算法,在算法题中遇到二叉树经常优先考虑递归算法。同时二叉树中的二叉搜索树也是常用的,主要结合中序遍历有序的特性。
二叉树
二叉树结构:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x; }
}
二叉树遍历主要分为前序、中序、后序和层次遍历。二叉树的深度优先搜索(DFS)和广度优先搜索(BFS)。
力扣关于二叉树的算法
1)剑指offer55_Ⅰ:二叉树的深度
题目:输入一棵二叉树的根节点,求该树的深度。
解题思路:递归左右子树的深度,最后比较左右子树深度加1。
算法代码:
class Solution {
//递归实现
public int maxDepth(TreeNode root) {
if(root==null){
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return Math.max(left,right)+1;
}
}
2)剑指offer55_Ⅱ:平衡二叉树
题目:输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
解题思路:递归,先找树的深度,再根据树的深度递归判断平衡二叉树。
算法代码:
class Solution {
public boolean isBalanced(TreeNode root) {
if(root==null) return true;
if(Math.abs(getHeigth(root.left)-getHeigth(root.right))<=1){
return isBalanced(root.left) && isBalanced(root.right);
}
return false;
}
public int getHeigth(TreeNode root){
if(root==null) return 0;
return Math.max(getHeigth(root.left),getHeigth(root.right))+1;
}
}
3)剑指offer27:二叉树的镜像
题目:请完成一个函数,输入一个二叉树,该函数输出它的镜像。
例如输入:
4
/ \
2 7
/ \ / \
1 3 6 9
镜像输出:
4
/ \
7 2
/ \ / \
9 6 3 1
解题思路:递归左右子树的镜像,借助个临时节点暂时存储左(右)节点。
算法代码:
class Solution {
//递归
public TreeNode mirrorTree(TreeNode root) {
if(root == null){
return root;
}
TreeNode tmp = root.left;
root.left = mirrorTree(root.right);
root.right = mirrorTree(tmp);
return root;
}
}
4)剑指offer68_Ⅰ:二叉树最近公共祖先
题目:给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
解题思路:递归左右子树,判断情况:
- 一个左子树一个右子树
- 都在左子树
- 都在右子树
- 一个是自身,另一个在子树
算法代码:
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root,TreeNode p, TreeNode q) {
if(root == null) return null;
if(p == root || q == root) return root;
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if(left!=null && right!=null) return root; //一个左子树一个右子树,最近祖先是root
if(left==null){
//都在左子树或都在右子树
return right;
}else{
return left;
}
}
}
5)剑指offer31:从上到下打印二叉树Ⅰ
题目:从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
解题思路:使用队列对二叉树进行层次遍历,即广度优先搜索BFS。返回一层,可以直接将节点存储到list中输出。
算法代码:
class Solution {
public int[] levelOrder(TreeNode root) {
if(root==null) return new int[0]; //new int[0] 表示动态分配一个长度为0的int数组
Queue<TreeNode> queue = new LinkedList<TreeNode>(); //创建队列进行层次遍历
ArrayList<Integer> list = new ArrayList<Integer>(); //创建list存储值
queue.offer(root);
while(!queue.isEmpty()){
TreeNode node = queue.poll();
list.