二叉树基础面试
1.二叉树的前序遍历(1:42)
思路
因为代码要求把遍历的结果放到顺序表中
所以首先应该创建一个顺序表
其次判断链表是否为空
然后把以前输出操作改为添加
然后递归遍历左子树,把遍历出的结果添加到顺序表中
然后递归遍历右子树,巴蒂鬼出来的结果添加到顺序表中
注意:顺序表的添加操作,add(),addAll();
代码
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result= new ArrayList<>();
if(root==null){
return result;
}
//先访问根节点,把值插入到result中
result.add(root.val);
//通过处理左子树,也会遇到一些点,直接插入
result.addAll(preorderTraversal(root.left));
//通过处理右子树,也会遇到一些点,直接插入
result.addAll(preorderTraversal(root.right));
return result;
}
2.二叉树的中序遍历
思路
因为代码要求把遍历的结果放到顺序表中
所以首先应该创建一个顺序表
其次判断链表是否为空
然后递归遍历左子树,把遍历出的结果添加到顺序表中
然后把以前输出操作改为添加
然后递归遍历右子树,巴蒂鬼出来的结果添加到顺序表中
注意:顺序表的添加操作,add(),addAll();
代码
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result=new ArrayList<>();
if(root==null){
return result;
}
//递归遍历左子树
result.addAll(inorderTraversal(root.left));
//把打印操作变为添加操作
result.add(root.val);
result.addAll(inorderTraversal(root.right));
return result;
}
3.二叉树的后续遍历
思路
因为代码要求把遍历的结果放到顺序表中
所以首先应该创建一个顺序表
其次判断链表是否为空
然后递归遍历左子树,把遍历出的结果添加到顺序表中
然后递归遍历右子树,巴蒂鬼出来的结果添加到顺序表中
然后把以前输出操作改为添加
注意:顺序表的添加操作,add(),addAll();
代码
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result= new ArrayList<>();
if(root==null){
return result;
}
//先访问根节点,把值插入到result中
result.add(root.val);//因为是Integer类型,所以只能添加root.val;
//通过处理左子树,也会遇到一些点,直接插入
result.addAll(preorderTraversal(root.left));
//通过处理右子树,也会遇到一些点,直接插入
result.addAll(preorderTraversal(root.right));
return result;
4.检查两棵树是否相同
思路
首先判断两个树是不是相同
先比较两个树的根节点的值是不是相同
如果根节点相同,再递归比较两个数的左子树是否相同,再递归比较两个树的右子树是否相同
如果三个条件同时具备,就认为他们相同。
注意:除上面中序+先序+后序,先序加中序遍历也ok
代码
public boolean isSameTree(TreeNode p, TreeNode q) {
//首先判断是否为空
if(p==null && q==null){
return true;
}
if(p==null || q==null){
return false;
}
//都不为空,然后判断根节点是否为空
if(p.val!=q.val){
return true;
}
//递归遍历左子树和右子树
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
5.另一颗树的子树
给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。
思路
遍历子树,看s上的某个节点对应的子树,是否和t这个树相等
即:遍历s,看当前节点对应的子树是否和t这个树相等
如果不相等,再递归遍历判定s的左子树是否包含 t,在递归遍历
s的右子树是否包含t,
代码
public boolean isSameTree(TreeNode p,TreeNode q){
//判断两个数是否相等
if(p==null && q==null){
return true;
}
if(p==null || q==null){
return false;
}
if(p.val != q.val){
return false;
}
return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
public boolean isSubtree(TreeNode s, TreeNode t) {
if(s==null){
return false;
}
//先判断当前节点是否相同,如果相同,返回true,如果不同,继续
boolean ret=isSameTree(s,t);
if(ret){
return ret;
}
// if(s.val==t.val){
// return ret;
// }
//看s的左子树是否包含t,s的右子树是否包含t
return isSubtree(s.left,t) ||isSubtree(s.right,t);
}
6.二叉树的最大深度
思路
求高度/求深度=1+max(左子树的高度+右子树的高度)
代码
7.判断一颗二叉树是否是平衡二叉树
思路
这棵树任意左右子树的高度差不超过1
代码
public static int getHeight(TreeNode root){
if(root==null){
return 0;
}
int leafHeight=getHeight(root.left);
int rightHeight=getHeight(root.right);
return 1+(leafHeight >rightHeight ? leafHeight : rightHeight);//切记必须加括号
}
public boolean isBalanced(TreeNode root) {
//空树
if(root==null){
return true;
}
//只有一个节点的树
if(root.left==null && root.right==null){
return true;
}
//访问操作
//判断左子树的高度和右子树的高度,并求差值
int ret1= getHeight(root.left);
int ret2=getHeight(root.right);
if(ret1-ret2>1 || ret1-ret2<-1){
return false;
}
//递归处理左右子树的情况
//要求左子树和右子树都是平衡的,才能说明整个子树是平衡的
// isBalanced(root.left);
// isBalanced(root.right);
return isBalanced(root.left) && isBalanced(root.right) ;
}
8.对称二叉树
思路
对称和根结点关系不大
主要看左右子树是否为镜像关系
比较左右子树的镜像关系=左右子树根节点的值是不是相等&&左子树的左子树和右子树的右子树是不是镜像关系&&左子树的右子树和右子树的左子树是不是镜像关系
专门写一个方法判断左右子树是不是镜像关系
代码
public boolean isMirror(TreeNode p,TreeNode q){
if(p==null && q==null){
return true;
}
//一个为空,一个不为空,一定不是镜像关系
if(p==null || q==null){
return false;
}
//如果根节点值是否相同
if(p.val !=q.val){
return false;
}
return isMirror(p.left,q.right) && isMirror(p.right,q.left);
}
public boolean isSymmetric(TreeNode root) {
if(root==null){
return true;
}
//写一个方法判断左右子树是不是镜像关系
return isMirror(root.left,root.right);
}