《剑指Offer》之二叉树系列(1)

1.输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

分析:
判断root1和root2的根结点是否相同,相同则进一步判断root1的子树和root2的子树是否相同。
root1和root2的根结点不同,则用roo1的左右子树跟root2比较,直到root1为空时结束。

当root1为null 且root2不为null,返回false;
当root2为null时,返回false;

//判断是否是子树,
    public boolean HasSubtree(TreeNode root1, TreeNode root2) {
        boolean flag = false;
        //根结点相同继续判断
        if (root1 != null && root2 != null) {
            if (root1.val == root2.val) {
                flag = HasSubtree2(root1, root2);
            }
            //根结点不同,用root1的子结点和root2的根结点比较
            if (!flag) {
                flag = HasSubtree(root1.left, root2);
            }
            if (!flag) {
                flag = HasSubtree(root1.right, root2);
            }
        }
        return flag;
    }

    public boolean HasSubtree2(TreeNode root1, TreeNode root2) {
        if (root1 == null && root2 != null)
            return false;
        if (root2 == null)
            return true;
        if (root1.val != root2.val)
            return false;
        return HasSubtree2(root1.left, root2.left)
                && HasSubtree2(root1.right, root2.right);
    }

2.操作给定的二叉树,将其变换为源二叉树的镜像。

二叉树的镜像定义:源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5

分析:
左右子树交换即可

public void Mirror(TreeNode root) {
        if(root == null)
            return;
        if(root.left == null && root.right == null)
            return;

        TreeNode pTemp = root.left;
        root.left = root.right;
        root.right = pTemp;

        if(root.left != null)
            Mirror(root.left);
        if(root.right != null)
            Mirror(root.right);
    }

3.二叉树的前序遍历和中序遍历的结果,重建二叉树

例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

分析:
pre为前序遍历数组,in为中序遍历数组。
用中序遍历的数组作为循环条件,当中序数组遍历到的值等于前序数组的第一个值时in[i]==pre[startPre],此时在中序遍历数组中,in[i]为root,in[ i] 之前的为左子树,之后的为右子树。

递归调用左子树和右子树。

public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        TreeNode tree = reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
        return tree;
    }
//pre为前序遍历数组,startPre为前序遍历数组的起点,endPre为前序遍历数组的终点,In为中序遍历
      private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
         if(startPre>endPre||startIn>endIn)
              return null;
          TreeNode root = new TreeNode(pre[startPre]);
          int i=startIn;
          for(;i<endIn;i++){
              if(in[i]==pre[startPre]){
                 break;
              }
          }
          //左子树长度
          int leftlength = i-startIn;
          root.left=reConstructBinaryTree(pre, startPre+1, startPre+leftlength, in, startIn, i-1);
          root.right =reConstructBinaryTree(pre, startPre+1+leftlength, endPre, in, i+1, endIn);
          return root;
      }

4.从上往下打印出二叉树的每个节点,同层节点从左至右打印。

利用队列的先进先出原则

public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
        ArrayList<Integer> array = new ArrayList<Integer>();
        if(root==null)return array;
        Deque<TreeNode> deque = new LinkedList<TreeNode>();
        deque.add(root);
        while(!deque.isEmpty()){
            TreeNode t = deque.pop();
            array.add(t.val);
            if(t.left!=null)
                deque.add(t.left);
            if(t.right!=null)
                deque.add(t.right);
        }
        return array;
    }

例如:
8
/ \
6 10
/ \ / \
5 7 9 11 这样一个二叉树,打印
第一次循环:先将8加入队列,弹出队首的值添加进List,左子树不为null,加入6,右子树不为null,加入10,
此时队列为 8 6 10
第二次循环:弹出6,6的左子树不为空,加入5,右子树不为空,加入7,
此时队列为 10 5 7

循环…执行,List中的值是 按层存入的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值