二叉树遍历的非递归实现
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;
}
}