数据结构与算法--二叉树

二叉树遍历的非递归实现

1.前序遍历
二叉树前序遍历时,按照中、左、右的顺序遍历。非递归遍历时,新建一个栈,把头节点放入栈中,当栈不为空时,循环从栈里取节点,对于取出的每个节点,先把其右子树放入栈中,再把其左子树放入栈中。因为栈是先入后出的,后放入的左子树,就会先于右子树遍历,从而实现前序中、左、右顺序的遍历。
代码:
public static void prePrint(TreeNode treeNode){
        Stack<TreeNode> stack = new Stack<>();
        stack.push(treeNode);
        while (!stack.isEmpty()){
            treeNode = stack.pop();
            System.out.print(treeNode.val + " ");
            if (treeNode.right != null){
                stack.push(treeNode.right);
            }
            if (treeNode.left != null){
                stack.push(treeNode.left);
            }
        }
        System.out.println();
    }
2.中序遍历
中序遍历的顺序是左、中、右,使用一个栈实现, 对于头节点,一直遍历其左子树并依次放入栈中,遍历到终点后,开始出栈并打印。每一个出栈节点,如果有右子树,则将该右子树、该右子树的所有左子树依次放入栈中。
代码:
public static void midPrint(TreeNode treeNode){
        Stack<TreeNode> stack = new Stack<>();
        while (treeNode != null || !stack.isEmpty()){
            if (treeNode != null){
                stack.push(treeNode);
                treeNode = treeNode.left;
            }else {
                treeNode = stack.pop();
                System.out.print(treeNode.val + " ");
                treeNode = treeNode.right;
            }

        }
        System.out.println();
    }
3.后序遍历
后序遍历使用两个栈实现,前序遍历实现了中、左、右的遍历顺序,在前序遍历的循环中,对于出栈节点,如果先把其左子树放入栈中,再把其右子树放入栈中,那么遍历顺序就变成了中、右、左,最后使用第二个栈来逆序这个遍历顺序,把中、右、左变为左、右、中,就是后序遍历。
public static void postPrint(TreeNode treeNode){
        Stack<TreeNode> stack1 = new Stack<>();
        Stack<TreeNode> stack2 = new Stack<>();
        stack1.push(treeNode);
        while (!stack1.isEmpty()){
            treeNode = stack1.pop();
            stack2.push(treeNode);
            if (treeNode.left != null){
                stack1.push(treeNode.left);
            }
            if (treeNode.right != null){
                stack1.push(treeNode.right);
            }
        }
        while (!stack2.isEmpty()){
            System.out.print(stack2.pop().val + " ");
        }
        System.out.println();
    }

LeetCode_98:判断一棵树是否是二叉搜索树

Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than the node’s key.
Both the left and right subtrees must also be binary search trees.

遍历每个节点时,传入该节点左右两侧的边界值,判断节点值是否大于左侧边界、小于右侧边界。
class Solution {
    public boolean isValidBST(TreeNode root) {
        return helper(root,Long.MIN_VALUE,Long.MAX_VALUE);
    }
    public boolean helper(TreeNode root,long left,long right){
        if (root == null) return true;
        if (root.val >= right || root.val <= left) return false;
        return helper(root.left,left,root.val) && helper(root.right,root.val,right);
    }
}

LeetCode_235:求二叉搜索树的最近公共祖先。

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
在这里插入图片描述
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.

遍历节点时,如果该节点比两个节点p、q的值都大,则往该节点的左子树方向遍历;如果该节点比两个节点p、q的值都小,则往该节点的右子树方向遍历。
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root.val > p.val && root.val > q.val){
            return lowestCommonAncestor(root.left,p,q);
        }else if (root.val < p.val && root.val < q.val){
            return lowestCommonAncestor(root.right,p,q);
        }else {
            return root;
        }
    }
}

LeetCode_236:求二叉树的最近公共祖先。

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
在这里插入图片描述
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q){
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left,p,q);
        TreeNode right = lowestCommonAncestor(root.right,p,q);
        //如果左右子树都不为空,则该节点就是公共祖先
        if (left != null && right != null){
            return root;
        }
        return left == null ? right : left;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值