数据结构与算法之二叉树训练营

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/boker_han/article/details/83719693

二叉树的深度(DFS-递归)

	public int TreeDepth(TreeNode root) {
	        if(root == null)
	            return 0;
	        //递归求左子树的深度
	        int left = TreeDepth(root.left);
	        //递归求右子树的深度
	        int right = TreeDepth(root.right);
	        //返回当前节点为根节点的子树的深度
	        return Math.max(left,right) + 1;
	}

输入一棵二叉树,判断该二叉树是否是平衡二叉树

输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)

实现两个函数,分别用来序列化和反序列化二叉树

找出二叉树中序遍历中给定节点的下一个节点

	public TreeLinkNode GetNext(TreeLinkNode node){
	        if(node == null)
	            return node;
	        //给定节点有右子树
	        if(node.right != null){
	            TreeLinkNode right = node.right;
	            while(right.left != null){
	                right = right.left;
	            }
	            return right;
	        }
	        while(node.next != null){
	            if(node.next.left == node){
	                return node.next;
	            }
	            node = node.next;
	        }
	        return null;
    }

给定二叉树的前序遍历数组和中序遍历数组,重建该二叉树并返回

	 public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
	        //输入参数合法性校验
	        if(pre == null || in == null || pre.length <= 0 || in.length != pre.length){
	            return null;
	        }
	        //调用递归重建二叉树逻辑
	        TreeNode root = constructCore(pre,0,pre.length-1,in,0,in.length-1);
	        return root;
	    }
	    private TreeNode constructCore(int[] pre,int beginPre,int endPre,int[] in,int beginIn,int endIn){
	        //递归终止条件,当子树中没有元素时,直接返回null
	        if(beginPre > endPre || beginIn > endIn){
	            return null;
	        }
	        //返回当前前序遍历子序列中的第一个元素,该元素为子树节点
	        TreeNode root = new TreeNode(pre[beginPre]);
	        //循环查找当前子树根节点在中序遍历子序列中的位置,并划分左右子树,进行递归
	        for(int i = beginIn ; i <= endIn ; i++){
	            if(pre[beginPre] != in[i])
	                continue;
	            //递归处理左子树
	            root.left = constructCore(pre,beginPre+1,beginPre+i-beginIn,in,beginIn,i-1);
	            //递归处理右子树
	            root.right = constructCore(pre,beginPre+i-beginIn+1,endPre,in,i+1,endIn);
	            break;
	        }
	        return root;
	    }

输入两棵二叉树A,B,判断B是不是A的子结构

	  public boolean HasSubtree(TreeNode root1,TreeNode root2) {
	        //输入参数合法性校验
	        if(root1 == null || root2 == null)
	            return false;
	        boolean result = false;
	        //当前节点与二叉树B根节点相等,进行子树递归判断
	        if(root1.val == root2.val)
	            result = isSubtree(root1.left,root2.left) && isSubtree(root1.right,root2.right);
	        //当前节点与二叉树节点不相等,遍历左子树
	        if(!result)
	            result = HasSubtree(root1.left,root2);
	        //当前节点的左子树中没有二叉树B的结构,遍历右子树
	        if(!result)
	            result = HasSubtree(root1.right,root2);
	        return result;
	    }
	    //递归子树查找二叉树B是否存在
	    private boolean isSubtree(TreeNode root1,TreeNode root2){
	        //如果二叉树B走到null,说明这条支路是符合的
	        if(root2 == null)
	            return true;
	        //如果还没走完当前分支,继续比较
	        if(root1 != null)
	            if(root1.val == root2.val)
	                return isSubtree(root1.left,root2.left) && isSubtree(root1.right,root2.right);
	        return false;
	    }

层序遍历二叉树(BFS-队列)

	public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
	        //返回的层序遍历结果
	        ArrayList<Integer> result = new ArrayList<>();
	        if(root == null)
	            return result;
	        //根据层序遍历的特点符合队列的先进先出,使用队列作为中间容器,存放每一层的元素
	        Queue<TreeNode> queue = new LinkedList<>();
	        queue.offer(root);
	        while(!queue.isEmpty()){
	            //记录每一层的非空节点数目
	            int size = queue.size();
	            //遍历记录节点的值,并存储下一层的非空节点
	            for(int i = 0; i < size; i++){
	                TreeNode cur = queue.poll();
	                result.add(cur.val);
	                if(cur.left != null)
	                    queue.offer(cur.left);
	                if(cur.right != null){
	                    queue.offer(cur.right);
	                }
	            }
	        }
	        return result;
	    }

之字形遍历二叉树(栈)

	public ArrayList<ArrayList<Integer> > Print(TreeNode root) {
	        //返回结果
	        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
	        if(root == null)
	            return result;
	        //当前层的节点栈
	        Stack<TreeNode> cur = new Stack<>();
	        cur.push(root);
	        //标志子节点入队方向
	        boolean flag = true;
	        while(!cur.isEmpty()){
	            //当前层的节点个数
	            int size = cur.size();
	            //存放当前层的遍历结果
	            ArrayList<Integer> temp = new ArrayList<>();
	            //下一层的节点栈
	            Stack<TreeNode> next = new Stack<>();
	            //从左向右入栈子节点
	            if(flag){
	                for(int i = 0; i < size; i++){
	                    TreeNode current = cur.pop();
	                    temp.add(current.val);
	                    if(current.left != null)
	                        next.push(current.left);
	                    if(current.right != null)
	                        next.push(current.right);
	                }
	            //从右向左入栈子节点
	            }else{
	                for(int i = 0; i < size; i++){
	                    TreeNode current = cur.pop();
	                    temp.add(current.val);
	                    if(current.right != null)
	                        next.push(current.right);
	                    if(current.left != null)
	                        next.push(current.left);
	                }
	            }
	            //更新子节点入栈顺序
	            flag = !flag;
	            //添加当前层的遍历结果
	            result.add(temp);
	            //更新下一次处理的节点栈
	            cur = next;
	        }
	        return result;
	 }

判断是否为对称二叉树 (递归)

	public boolean isSymmetrical(TreeNode root){
	        if(root == null)
	            return true;
	        return isSymmetricalCore(root,root);
	    }
	    public boolean isSymmetricalCore(TreeNode orign,TreeNode mirror){
	        //叶子结点分别相等,返回
	        if(orign == null && mirror == null)
	            return true;
	        //不同为叶子结点。返回
	        if(orign == null || mirror == null)
	            return false;
	        //皆不是叶子结点,但不相等,返回
	        if(orign.val != mirror.val)
	            return false;
	        //当前节点相同,继续遍历子节点
	        return isSymmetricalCore(orign.left,mirror.right)&&isSymmetricalCore(orign.right,mirror.left);
	    }

判断给定数组是否为二叉搜索树的后序遍历

	 public boolean VerifySquenceOfBST(int [] sequence) {
	        //如果参数不合法,返回false
	        if(sequence == null || sequence.length <= 0)
	            return false;
	        return core(sequence,0,sequence.length-1);
	    }
	    //核心逻辑,递归判断左右子树是否为二叉搜索树
	    private boolean core(int[] sequence, int begin, int end){
	        //子树中只有一个节点或两个节点,此时子树结构必定符合二叉搜索树结构
	        if(begin >= end || begin == end - 1)
	            return true;
	        //记录左右子树的分界点
	        int border = end;
	        int i = begin;
	        //循环找出右子树的第一个节点
	        for(; i < end; i++){
	            if(sequence[i] > sequence[end]){
	                border = i;
	                break;
	            }
	        }
	        //检测右子树中的节点是否都大于根节点
	        for(; i < end; i++){
	            if(sequence[i] < sequence[end])
	                return false;
	        }
	        //递归判断左右子树结构是否为二叉搜索树
	        return core(sequence,begin,border-1)&&core(sequence,border,end-1);
	  }

猜你喜欢

转载自blog.csdn.net/boker_han/article/details/83719693