剑指offer之二叉树

二叉树的定义

public class TreeNode {
     int val;
     TreeNode left;
     TreeNode right;
     TreeNode(int x) { val = x; }
  }

注意特殊二叉树: 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

  1. 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
    分析: 根据二叉树前序遍历和中序遍历的规则,前序遍历结果的第一个元素为根节点,根据中序遍历,找到根节点,根节点左侧的元素为左子树,根节点右侧的元素为右子树,然后将左右子树分布重复上述过程,直到叶子节点。

    代码如下

    public class Solution {
        public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
            TreeNode root = reConstructBinaryTree(pre,0,pre.length - 1,in,0,in.length - 1);
            return root;
        }
        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]);
            for (int i = startIn;i <= endIn;i++){
                if (in[i] == pre[startPre]) {
                    root.left = reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
                    root.right = reConstructBinaryTree(pre,startPre+i-startIn+1,endPre,in,i+1,endIn);
                    break;
                }
            }
            return root;
        }
    }
    
  2. 操作给定的二叉树,将其变换为源二叉树的镜像。
    在这里插入图片描述
    分析: 将二叉树的左右子树交换。

    public class Solution {
        public void Mirror(TreeNode root) {
            if (root == null || (root.left == null && root.right == null)) {
                return null;
            }
            TreeNode tmp = null;
            tmp = root.left;
            root.left = root.right;
            root.right = tmp;
            if (root.left != null) {
                Mirror(root.left);
            }
            if (root.right != null) {
                Mirror(root.right);
            }
        }
    }
    

    注意: 两个if语句的使用。

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

    分析: 借助队列实现二叉树的层序遍历。
    代码如下:

    public class Solution {
        public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
            ArrayList<Integer> list = new ArrayList<Integer>();
            ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
            if (root == null) {
                return list;
            }
            queue.add(root);
            while (queue.size() != 0) {
                TreeNode tmp = queue.remove(0);
                if (tmp.left != null) {
                    queue.add(tmp.left);
                }
                if (tmp.right != null) {
                    queue.add(tmp.right);
                }
                list.add(tmp.val);
            }
            return list;
        }
    }
    
  4. 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

    分析: 搜索二叉树是一种特殊的二叉树,一定满足 左子树<根节点<右子树 ,根据后序遍历的特点我们可以得到,最后一个节点为根节点,从数组的第一个元素开始查找,找到第一个大于根节点的元素,其左侧即为根节点的左子树,其及其右侧为根节点的右子树,判断其右子树是否满足均小于根节点。然后重复上述过程。
    代码如下:

    public class Solution {
        public boolean VerifySquenceOfBST(int [] sequence) {
            int n = sequence.length;
            if (n == 0) {
                return false;
            } else if (n == 1) {
                return true;
            } else {
                return judge(sequence, 0, n-1);
            }
        }
        
        public boolean judge(int[] a, int start, int end) {
            if (start >= end) {
                return true;
            }
            int i = start;
            while (a[i] < a[end]) {
                i++;
            }
            for (; i < end; i++) {
                if (a[i] < a[end]) {
                    return false;
                }
            }
            return judge(a, start, i-1) && judge(a, i, end-1);
        }
    }
    
  5. 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

    分析: 利用递归实现,具体见代码,注意到达叶子节点后,需要返回父节点。

    public class Solution {
        ArrayList<ArrayList<Integer>> listAll = new ArrayList<ArrayList<Integer>> ();
        ArrayList<Integer> list = new ArrayList<Integer> ();
        public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
            if (root == null) {
                return listAll;
            }
            list.add(root.val);
            target = target - root.val;
            if (target == 0 && root.left == null && root.right == null) {
                listAll.add(new ArrayList<Integer>(list));
            }
            if (root.left != null) {
                FindPath(root.left, target);
            }
            if (root.right != null) {
                FindPath(root.right, target);
            }
            list.remove(list.size() - 1);
            return listAll;
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值