二叉树

目录

一、概念:

二、性质

三、遍历:

四、程序

前序遍历

层序遍历:

比较两棵树是否相同

判断另一颗树的子树

判断是否平衡二叉树

判断是否对称二叉树

找二叉树中两个结点的公共祖先

二叉树创建字符串

二叉搜索树转换为一个排序的双向链表


一、概念:

  • 树是一种非线性的数据结构.
一棵二叉树是结点的一个有限集合,该集合:
1. 或者为空
2. 或者是由 一个根节 点加上两棵别称为 左子树 右子树 的二叉树组成。

二、性质

  •  对任何一棵二叉树, 如果其叶结点个数为 n0, 度为2的非叶结点个数为 n2,则有n0n21
  •  具有n个结点的完全二叉树的深度klog_2{(n+1)}上取整
  • 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的顺序对所有节点从0开始编号,则对于序号为i的结点有i>0双亲序号:(i-1)/2i=0i为根结点编号,无双亲结点 2i+1<n,左孩子序号:2i+1,否则无左孩子;2i+2<n,右孩子序号:2i+2,否则无右孩子;

三、遍历:

前序遍历 中序遍历 后序遍历 层序遍历

本质:就是在不同的时机,访问数据

前序遍历:根-左子树-右子树

中序遍历:左子树-根-右子树

后序遍历:左子树-右子树-根

四、程序

前序遍历

void preOrder(TreeNode root){
   if(root==null){
     return;
}
System.out.print(root.val+" ");
preOrder(root.left);
preOrder(root.right);
}

层序遍历:

public void leveOrder(Node root){
        Queue<Node> queue =new LinkedList<>();
        if (root!=null){
            queue.offer(root);
        }
        while (!queue.isEmpty()){
            Node cur=queue.poll();//出队列
            System.out.print(cur.val+" ");
            if (cur.left!=null){
                queue.offer(cur.left);
                if (cur.right!=null){
                    queue.offer(cur.right);
                }
            }
        }
    }

比较两棵树是否相同

  1. 检查根节点:结构、值
  2. 递归左树和右树
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p!=null&&q==null||p==null&&q!=null){
            return false;
        }
     if(p==null&&q==null){
         return true;
     }
     if(p.val!=q.val){
         return false;
     }
     return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
    }
}

判断另一颗树的子树

  1. 判断subRoot是不是和root相同
  2. 判断subRoot是不是和root左子树
  3. 判断subRoot是不是和root右子树

    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if(root==null||subRoot==null){
            return false;
        }
  if(isSameTree(root,subRoot)){//1
      return true;
  }if(isSubtree(root.right,subRoot)){//2
      return true;
  }
  if(isSubtree(root.left,subRoot)){//3
      return true;
  }
  return false;
   }

判断是否平衡二叉树

平衡:每颗子树左右高度差不超过1

  1. root平衡
  2. root.left平衡
  3. root.right平衡
class Solution {
    public int maxDepth(TreeNode root) {
    if(root==null){
        return 0;
    }
    int leftH=maxDepth(root.left);
    int rightH=maxDepth(root.right);
    return leftH>rightH?leftH+1:rightH+1;
    }
    public boolean isBalanced(TreeNode root) {
        if(root==null){
            return true;
        }
        int leftR=maxDepth(root.left);
        int rightR=maxDepth(root.right);
        return Math.abs(leftR-rightR)<=1&&isBalanced(root.left)&&isBalanced(root.right);
    }
}

判断是否对称二叉树

  1. 一个为空,一个不为空
  2. 两个皆空
  3. 判断值是否相同
class Solution {
    public boolean isSymmetric(TreeNode root) {
    if(root==null){
        return false;
    }
    return isSomechild(root.left,root.right);
    }
 public boolean isSomechild(TreeNode leftTree,TreeNode rightTree){
        if(leftTree==null&&rightTree!=null||leftTree!=null&&rightTree==null){
            return false;
        }
        if(leftTree==null&&rightTree==null){
            return true;
        }
        if(leftTree.val!=rightTree.val){
            return false;
        }
       return isSomechild(leftTree.left,rightTree.right)&&isSomechild(leftTree.right,rightTree.left);
    }
}

找二叉树中两个结点的公共祖先

  1. 左树,右树中查找都不为空,root为公共祖先
  2. 左树查找为空,右树查找不为空,证明两个节点都在右树,公共祖先为右树第一个
  3. 右树查找为空,左树查找不为空,证明两个节点都在左树,公共祖先为左树第一个 
 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null){
            return null;
        }
        if(root==p||root==q){
            return root;
        }
    
        TreeNode leftTree=lowestCommonAncestor( root.left, p, q);//在左树中查找p、q
        TreeNode rightTree=lowestCommonAncestor( root.right, p, q);//在右树中查找p、q
        if(leftTree!=null&&rightTree!=null){
            return root;
        }
        if(leftTree!=null&&rightTree==null){
            return leftTree;
        }
        if(leftTree==null&&rightTree!=null){
            return rightTree;
        }
        return null;
    }
}

二叉树创建字符串

public String tree2str(TreeNode root) {
        StringBuilder sb=new StringBuilder(); 
        if(root==null){
            return null;
        }
        tree2strchild(root,sb);
        return new String(sb);
    }


   public void tree2strchild(TreeNode t,StringBuilder sb){
    if(t==null){
        return;
    }
    sb.append(t.val);
     if(t.left!=null){
      sb.append("(");
      tree2strchild(t.left,sb);
      sb.append(")");
    }else{
        if(t.right==null){
            return;
        }
        else{
            sb.append("()");
        }
    }

    if(t.right==null){
        return;
    }else{
        sb.append("(");
        tree2strchild(t.right,sb);
        sb.append(")");
    }
    }

二叉搜索树转换为一个排序的双向链表

  • 二叉搜索树:左边都比跟小,右边都比根大。
  • 排序:中序遍历这个二叉树
  • 修改前驱、后继的指向
public TreeNode prev=null;
    public void Convertchild(TreeNode pcur){
        if(pcur==null){
            return;
        }
        Convertchild(pcur.left);//中序遍历拿到一个节点,开始修改当前节点的指向
        pcur.left=prev;
        if(prev!=null){
        prev.right=pcur;
        }
        prev=pcur;
        Convertchild(pcur.right);
    }
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
            return null;
        }
        Convertchild(pRootOfTree);
        TreeNode head=pRootOfTree;
        while(head.left!=null){
            head=head.left;
        }
        return head;
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值