日升时奋斗,日落时自省
目录
一、二叉树练习
习题一
相同的两个树,认为结构以及数值都是相同的树
条件解析:
(1)判断空树
(2)结构相同:都存在左子树或者存在右子树
(3)数值相同:在结构相同的基础上确定其相同结构位置的数值也相同
public boolean isSameTree(TreeNode p, TreeNode q) {
//首先判断空
//然后就是判断结构是否相同
//在判断数值是否相同
if (p == null && q == null) { //判断为空是也算相同
return true;
}
if (p == null && q != null || p != null && p == null) { //一颗树为空,另一颗树不为空
return false;
}
if (p.val != q.val) { //当前树结构是是相同,但是值不相同,也不是相同的树
return false;
}
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); //同时遍历树的左边,右边
}
习题二
判断另一颗树的子树,上一题已经判断了相同树的代码,改题可以将上一题的代码作为这题的子方法
条件解析:
(1)两颗树是否相同
(2)左子树是否与该树相同
(3)右子树是否与该树相同
(4)前面三个条件实现后会有问题,是null地址异常,需要在开始的判断空
//判断两课树是否相同
public boolean isSameTree(TreeNode p, TreeNode q) {
//首先判断空
//然后就是判断结构是否相同
//在判断数值是否相同
if (p == null && q == null) { //判断为空是也算相同
return true;
}
if (p == null && q != null || p != null && p == 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 root, TreeNode subRoot) {
if(root==null){ //判断空时为了防止root.left的null异常
return false;
}
//第一种情况就是两树都是相同的
if(isSameTree(root,subRoot)){ //判断两树是否相同
return true;
}
if(isSubtree(root.left,subRoot)){ //两树不相同的情况下,判断左子树与该树相同
return true;
}
if(isSubtree(root.right,subRoot)){ //左子树不能找到相同就是找右子树是否存在相同
return true;
}
return false;
}
习题三
什么是平衡二叉树:每个节点的左子树与右子树的高度差<2
条件解析:
(1)计算左子树高度
(2)计算右子树高度
(3)左子树高度-右子树高度<=1
特殊情况:
public boolean isBalanced(TreeNode root) {
if(root==null){
return true;
}
return getMax(root)>=0; //如果高度差大于等于零就是平衡二叉树
}
public int getMax(TreeNode root){
if(root==null){ //判空就是0
return 0;
}
int leftheight=getMax(root.left); //计算当前左子树的高度
int rightheight=getMax(root.right); //当前右子树的高度
if(Math.abs(leftheight-rightheight)<=1&&leftheight>=0&&rightheight>=0){
return Math.max(leftheight,rightheight)+1; //高度左右子树相减之后还有一个根节点的高度
}else {
return -1; //如果没有<=1就会为-1
}
}
习题三(简易思路)(复杂度O(
))
条件解析:
(1)写一个子方法计算树的高度
(2)在平衡二叉树的方法中调用树高度方法 求当前左子树高度,当前右子树高度
(3)左右子树高度差小于等于1,递归左右子树同时都满足平衡
public boolean isBalanced1(TreeNode root) {
if(root==null){
return true;
}
int leftside=getMax(root.left); //当前左子树的高度
int rightside=getMax(root.right); //当前右子树的高度
if(Math.abs(leftside-rightside)<=1&&isBalanced(root.left)&&isBalanced(root.right)){ //满足当前根节点的左子树与右子树的高度相减小于等于1左子树与右子树都是平衡的
return true;
}
return false;
}
public int getMax1(TreeNode root){ //计算树的高度
if(root==null){
return 0;
}
int leftHeight=getMax(root.left);
int rightHeight=getMax(root.right);
return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
}
习题四
条件解释:
(1)将一颗树分为两颗树来遍历
(2)一颗子树左遍历,另一颗子树右遍历
(3)涉及机构相同
(4)数值相同
//两颗子树是否完全对称
public boolean isSymmetric(TreeNode root) { //是不是对称树
if(root==null){
return true;
}
return isSymmetricChild(root.left,root.right); //两个子树是否完全对称
}
private boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree) {
if(leftTree==null&&rightTree==null){ //两颗树都是空树
return true;
}
if(leftTree!=null&&rightTree==null||leftTree==null&&rightTree!=null){ //两树结构不同
return false;
}
if(leftTree.val!=rightTree.val){ //两树结构相同,但是值不相同
return false;
}
return isSymmetricChild(leftTree.left, rightTree.right)&&isSymmetricChild(leftTree.right,rightTree.left); //对称方向遍历
}
习题五
先进行先序遍历的二叉树 后进行中序遍历
条件解释:
(1)可以先写一个中序遍历的方法
(2)获取字符串中每个字节,如果不是#的话,就可以进行新节点的建立
(3)每次字符串下标向后移动
(4)如果为#的话向后移动跳过
public static void main(String[] args) {
Main s=new Main();
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextLine()) { // 注意 while 处理多个 case
String str=in.nextLine();
TreeNode root=creatTree(str);
s.inorder(root);
}
}
public void inOrder1(TreeNode root){ //一个中序遍历
if(root==null){
return ;
}
inOrder1(root.left);
System.out.print(root.val+" ");
inOrder1(root.right);
}
private static int i=0;
private static TreeNode creatTree(String str){ //创建一个新的根节点
TreeNode rootnew=null;
if(str.charAt(i)!='#'){ //只要不等于#就是加入
rootnew=new TreeNode(str.charAt(i)); //新建一个节点
i++; //字符串加加
rootnew.left=creatTree(str); //先序遍历,先网左边放
rootnew.right=creatTree(str);
}else{
i++; //遇见#跳过
}
return rootnew; //最终返回当前根节点
}