数据结构和算法——二叉树

二叉树:树的每个节点最多只能有两个子节点。

树的效率:查找节点的时间取决于这个节点所在的层数,每一层最多有2n-1个节点,总共N层共有2n-1个节点,那么时间复杂度为O(logN),底数为2。

二叉搜索树要求:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

遍历:

  • 前序是根节点-左子树-右子树
  • 中序是左子树-根节点-右子树
  • 后序是左子树-右子树-根节点
二叉树的前、中、后序遍历
前序遍历
递归
public void preorderBT(BinaryTree root) {
        //结束条件
        if (root == null)
            return;
        //递归主体
        System.out.print(root.val + " ");
        preorderBT(root.left);
        preorderBT(root.right);
 
    }
非递归
/**
     * 前序遍历非递归方式实现
     * 非递归实现思路:二叉树遍历的递归实现很简单,也很容易理解,在进行非递归实现时,需要用到栈这种数据结构(为什么是栈,不是别的数据结构)。
     * 因为递归实现的过程就是程序自己在处理圧栈和弹栈,改用非递归实现时,用栈模拟系统的圧栈与弹栈,就可以了。
     */
    public List<Integer> preorderBT1(BinaryTree root) {
        List<Integer> preorderResult = new ArrayList<>();
        Stack<BinaryTree> stack = new Stack<>();
        BinaryTree currentNode = root;
        while (currentNode != null || !stack.isEmpty()) {
            //对于前序遍历,需要一直往二叉树的左子树上走,直道左子树走完。在走左子树的过程中需要输出遇到节点的值
            while (currentNode != null) {
                preorderResult.add(currentNode.val);
                stack.push(currentNode);
                currentNode = currentNode.left;
            }
            //左边的节点都走完了,需要改变节点方向
            if (!stack.isEmpty()) {
                currentNode = stack.pop();
                currentNode = currentNode.right;
            }
        }
        return preorderResult;
    }
中序遍历
递归
 public void inorderBT(BinaryTree root) {
        if (root == null)
            return;
        inorderBT(root.left);
        System.out.print(root.val + " ");
        inorderBT(root.right);
    }
非递归
/**
     * 中序遍历的非递归实现,与上述前序遍历类似,只有稍许不同,注意
     */
    public List<Integer> inorderBT1(BinaryTree root) {
        List<Integer> inorderResult = new ArrayList<>();
        Stack<BinaryTree> stack = new Stack<>();
        BinaryTree currentNode = root;
        while (currentNode != null || !stack.isEmpty()) {
            //一直向左,但是先不打印经历的节点的值
            while (currentNode != null) {
                stack.push(currentNode);
                currentNode = currentNode.left;
            }
            //到达最左边,打印并改变方向
            if (!stack.isEmpty()) {
                currentNode = stack.pop();
                inorderResult.add(currentNode.val);
                currentNode = currentNode.right;
            }
 
        }
        return inorderResult;
 
    }
后序遍历
递归
public void postorderBT(BinaryTree root) {
        if (root == null)
            return;
        postorderBT(root.left);
        postorderBT(root.right);
        System.out.print(root.val+" ");
    }
非递归
	/**
     * 后序遍历的非递归实现
     * 技巧:妙用前序遍历的非递归可以实现后序遍历的非递归实现,这里需要注意几点改变:后序时,先遍历右,再遍历左,最后将得到的结果反向就好了
     */
    public List<Integer> postorderBT1(BinaryTree root) {
        List<Integer> postorderResult = new ArrayList<>();
        Stack<BinaryTree> stack = new Stack<>();
        BinaryTree currentNode = root;
        while (currentNode != null || !stack.isEmpty()) {
            while (currentNode != null) {
                postorderResult.add(currentNode.val);
                stack.push(currentNode);
                currentNode = currentNode.right;
            }
            if (!stack.isEmpty()) {
                currentNode = stack.pop();
                currentNode = currentNode.left;
            }
        }
        Collections.reverse(postorderResult);
        return postorderResult;
    }
二叉树的最大深度
public int maxDepth(TreeNode root) {
       return root==null? 0 : Math.max(maxDepth(root.left), maxDepth(root.right))+1;
    }
平衡二叉树

思路:递归

	private boolean result = true;

    public boolean isBalanced(TreeNode root) {
        maxDepth(root);
        return result;
    }

    public int maxDepth(TreeNode root) {
        if (root == null)
            return 0;
        int l = maxDepth(root.left);
        int r = maxDepth(root.right);
        //左右子数最大深度差值大于1
        if (Math.abs(l - r) > 1)
            //不是平衡二叉树
            result = false;
        
        return 1 + Math.max(l, r);
    }
对称二叉树

思路:递归

 public boolean isSymmetric(TreeNode root) {
        return isMirror(root, root);
    }
    public boolean isMirror(TreeNode t1, TreeNode t2) {
        if (t1 == null && t2 == null) {
             return true;
        }
        if (t1 == null || t2 == null) {
            return false;
        }
        return (t1.val == t2.val)
                && isMirror(t1.right, t2.left)
                && isMirror(t1.left, t2.right);
    }
翻转二叉树
public TreeNode invertTree(TreeNode root) {
        if (root == null) {
        return null;
    }
    TreeNode right = invertTree(root.right);
    TreeNode left = invertTree(root.left);
    root.left = right;
    root.right = left;
    return root;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值