求二叉树的深度
前序遍历
中序遍历
后序遍历
分层遍历
二叉树分层左右交替遍历(先从左到右,再从右到左,交替)
求二叉树第K层的节点个数
二叉树中叶子节点的个数
判断两棵二叉树是否相同
判断两个树是否互相镜像
求二叉树的镜像
求二叉树中的节点个数
递归
/** * 求二叉树中的节点个数递归解法: O(n) * (1)如果二叉树为空,节点个数为0 * (2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1 */ public int getNodeNumRec(TreeNode root) { if (root == null) { return 0; } else { return getNodeNumRec(root.left) + getNodeNumRec(root.right) + 1; } }
迭代
public int getNodeNum(TreeNode root) { if (root == null) { return 0; } int count = 1; Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); while (!queue.isEmpty()) { TreeNode node = queue.remove(); if (node.left != null) { queue.add(node.left); count++; } if (node.right != null) { queue.add(node.right); count++; } } return count; }
求二叉树的深度
递归
/** * 求二叉树的深度递归解法: O(n) * (1)如果二叉树为空,二叉树的深度为0 * (2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1 */ public int getDepthRec(TreeNode root) { if (root == null) { return 0; } int left = getDepthRec(root.left); int right = getDepthRec(root.right); return Math.max(left, right) + 1; }
遍历
public int getDepth(TreeNode root) { if (root == null) { return 0; } int level = 0; int currentLevelNode = 1; int nextLevelNode = 0; Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); while (!queue.isEmpty()) { TreeNode node = queue.remove(); currentLevelNode--; if (node.left != null) { nextLevelNode++; queue.add(node.left); } if (node.right != null) { nextLevelNode++; queue.add(node.right); } if (currentLevelNode == 0) { level++; currentLevelNode = nextLevelNode; nextLevelNode = 0; } } return level; }
前序遍历
递归
/** * 前序遍历递归解法: * (1)如果二叉树为空,空操作 * (2)如果二叉树不为空:访问根节点,前序遍历左子树,前序遍历右子树 */ public void preorderTraversalRec(TreeNode root) { if (root == null) { return; } System.out.println(root.val); preorderTraversalRec(root.left); preorderTraversalRec(root.right); } //return list ArrayList<Integer> list = new ArrayList<>(); public ArrayList<Integer> preorderTraversalRec(TreeNode root){ if(root==null){ return list; } list.add(root.val); preorderTraversalRec(root.left); preorderTraversalRec(root.right); return list; }
非递归
public ArrayList<Integer> preorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); if (root == null) { return list; } Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); while (!stack.isEmpty()) { TreeNode cur = stack.pop(); list.add(cur.val); if (cur.right != null) { stack.push(cur.right); } if (cur.left != null) { stack.push(cur.left); } } return list; }
中序遍历
递归
/** * 中序遍历递归解法 * (1)如果二叉树为空,空操作。 * (2)如果二叉树不为空:中序遍历左子树,访问根节点,中序遍历右子树 */ public void inorderTraversalRec(TreeNode root) { if (root == null) { return; } inorderTraversalRec(root.left); System.out.println(root.val); inorderTraversalRec(root.right); }
非递归
public static ArrayList<Integer> inorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); if (root == null) { return list; } Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode cur = root; while (true) { while (cur != null) { stack.push(cur); cur = cur.left; } if (stack.isEmpty()) { break; } cur = stack.pop(); list.add(cur.val); cur = cur.right; } return list; }
后序遍历
递归
public void postorderTraversalRec(TreeNode root) { if (root == null) { return; } postorderTraversal(root.left); postorderTraversal(root.right); System.out.println(root.val); }
非递归
public ArrayList<Integer> postorderTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); if (root == null) { return list; } Stack<TreeNode> s = new Stack<TreeNode>(); // 第一个stack用于添加node和它的左右孩子 Stack<TreeNode> output = new Stack<TreeNode>();// 第二个stack用于翻转第一个stack输出 s.push(root); while (!s.isEmpty()) { // 确保所有元素都被翻转转移到第二个stack TreeNode cur = s.pop(); output.push(cur); // 把栈顶元素的左孩子和右孩子分别添加入第一个stack if (cur.left != null) { s.push(cur.left); } if (cur.right != null) { s.push(cur.right); } } while (!output.isEmpty()) { // 遍历输出第二个stack,即为后序遍历 list.add(output.pop().val); } return list; }
分层遍历
递归
public ArrayList<ArrayList<Integer>> levelTraversalRec(TreeNode root) { ArrayList<ArrayList<Integer>> ret = new ArrayList<ArrayList<Integer>>(); dfs(root, 0, ret); return ret; } private void dfs(TreeNode root, int level, ArrayList<ArrayList<Integer>> ret) { if (root == null) { return; } // 添加一个新的ArrayList表示新的一层 if (level >= ret.size()) { ret.add(new ArrayList<Integer>()); } ret.get(level).add(root.val); // 把节点添加到表示那一层的ArrayList里 dfs(root.left, level + 1, ret); // 递归处理下一层的左子树和右子树 dfs(root.right, level + 1, ret); }
非递归
public ArrayList<Integer> levelTraversal(TreeNode root) { ArrayList<Integer> list = new ArrayList<>(); if (root == null) { return list; } Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); while (!queue.isEmpty()) { TreeNode cur = queue.remove(); list.add(cur.val); if (cur.left != null) { queue.add(cur.left); } if (cur.right != null) { queue.add(cur.right); } } return list; }
二叉树分层左右交替遍历(先从左到右,再从右到左,交替)
public ArrayList<ArrayList<Integer>> zigzagLevelOrder(TreeNode root) { ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); if(root == null){ return result; } // 出栈顺序是从左到右 Stack<TreeNode> leftstack = new Stack<TreeNode>(); leftstack.push(root); // 出栈顺序是从右到左 Stack<TreeNode> rightstack = new Stack<TreeNode>(); boolean left = true; while(!leftstack.empty() || !rightstack.empty()){ ArrayList<Integer> list = new ArrayList<Integer>(); if(left){ int size = leftstack.size(); for(int i=0; i<size; i++){ TreeNode node = leftstack.pop(); list.add(node.val); if(node.left!=null){ rightstack.push(node.left); } if(node.right!=null){ rightstack.push(node.right); } } }else{ int size = rightstack.size(); for(int i=0;i<size;i++){ TreeNode node = rightstack.pop(); list.add(node.val); if(node.right!=null){ leftstack.push(node.right); } if(node.left!=null){ leftstack.push(node.left); } } } left=!left; result.add(list); } return result; }
求二叉树第K层的节点个数
递归:求以root为根的第k层节点数目 == 求以root.left 为根的k-1层(因为少了root那一层)节点数目 + 以root.right 为根的k-1层节点数目
/** * 求二叉树第K层的节点个数 递归解法: * (1)如果二叉树为空或者k<1返回0 * (2)如果二叉树不为空并且k==1,返回1 * (3)如果二叉树不为空且k>1,返回root左子树中k-1层的节点个数与root右子树k-1层节点个数之和 */ public int getNodeNumKthLevelRec(TreeNode root, int k) { if (root == null || k < 1) return 0; if (k == 1) return 1;
int numLeft = getNodeNumKthLevelRec(root.left, k - 1); int numRight = getNodeNumKthLevelRec(root.right, k - 1); return numLeft + numRight; }
非递归
// 与求二叉树深度迭代方法一样 public int getNodeNumKthLevel(TreeNode root, int k) { if (root == null) { return 0; } Queue<TreeNode> queue = new LinkedList<TreeNode>(); int i = 0; int currentLevelNodes = 1; int nextLevelNodes = 0; queue.add(root); while (!queue.isEmpty() && i < k) { TreeNode cur = queue.remove(); currentLevelNodes--; if (cur.left != null) { queue.add(cur.left); nextLevelNodes++; } if (cur.right != null) { queue.add(cur.right); nextLevelNodes++; } if (currentLevelNodes == 0) { currentLevelNodes = nextLevelNodes; nextLevelNodes = 0; i++; } } return currentLevelNodes; }
二叉树中叶子节点的个数
递归
public int getNodeNumLeafRec(TreeNode root) { if (root == null) return 0; if (root.left == null && root.right == null) return 1; return getNodeNumLeafRec(root.left) + getNodeNumLeafRec(root.right); }
非递归
// 基于分层遍历方法 public int getNodeNumLeaf(TreeNode root) { if (root == null) { return 0; } int leafNodes = 0; Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root); while (!queue.isEmpty()) { TreeNode cur = queue.remove(); if (cur.left != null) { queue.add(cur.left); } if (cur.right != null) { queue.add(cur.right); } if (cur.left == null && cur.right == null) { leafNodes++; } } return leafNodes; }
判断两棵二叉树是否相同
递归
/** * 判断两棵二叉树是否相同的树。 递归解法: * (1)如果两棵二叉树都为空,返回真 * (2)如果两棵二叉树一棵为空,另一棵不为空,返回假 * (3)如果两棵二叉树都不为空,如果对应的左子树和右子树都相同返回真,其他返回假 */ public boolean isSameRec(TreeNode t1, TreeNode t2){ if(t1==null && t2==null){ return true; } if(t1==null || t2==null){ return false; } if(t1.val==t2.val){ return isSameRec(t1.left, t2.left) && isSameRec(t2.right, t2.right); } return false; }
非递归
/** * 判断两棵二叉树是否相同的树(迭代) 遍历一遍即可,这里用preorder */ public boolean isSame(TreeNode r1, TreeNode r2) { if (r1 == null && r2 == null) { return true; } else if (r1 == null || r2 == null) { return false; } Stack<TreeNode> s1 = new Stack<TreeNode>(); Stack<TreeNode> s2 = new Stack<TreeNode>(); s1.push(r1); s2.push(r2); while (!s1.isEmpty() && !s2.isEmpty()) { TreeNode node1 = s1.pop(); TreeNode node2 = s2.pop(); if (node2 == null && node1 == null) { continue; } else if (node1 != null && node2 != null && node1.val == node2.val) { s1.push(node1.right); s1.push(node1.left); s2.push(node2.right); s2.push(node2.left); } else { return false; } } return true; }
判断两个树是否互相镜像
public boolean isMirrorRec(TreeNode r1, TreeNode r2) { if (r1 == null && r2 == null) { return true; } if (r1 == null || r2 == null) { return false; } if (r1.val != r2.val) { return false; } return isMirrorRec(r1.left, r2.right) && isMirrorRec(r1.right, r2.left); }
求二叉树的镜像
递归
public TreeNode mirrorCopyRec(TreeNode root) { if (root == null) { return null; } TreeNode newNode = new TreeNode(root.val); newNode.left = mirrorCopyRec(root.right); newNode.right = mirrorCopyRec(root.left); return newNode; }
非递归
// 1. 破坏原来的树,把原来的树改成其镜像 public void mirror(TreeNode root) { if (root == null) { return; } Stack<TreeNode> stack = new Stack<TreeNode>(); stack.push(root); while (!stack.isEmpty()) { TreeNode cur = stack.pop(); TreeNode temp = cur.left; cur.right = cur.left; cur.left = temp; if (cur.right != null) { stack.push(cur.right); } if (cur.left != null) { stack.push(cur.left); } } } // 2. 不破坏原来的树,返回一个新的镜像树 public static TreeNode mirrorCopy(TreeNode root) { if (root == null) { return root; } Stack<TreeNode> stack = new Stack<TreeNode>(); Stack<TreeNode> newStack = new Stack<TreeNode>(); stack.push(root); TreeNode newRoot = new TreeNode(root.val); newStack.push(newRoot); while (!stack.isEmpty()) { TreeNode cur = stack.pop(); TreeNode newCur = newStack.pop(); if (cur.right != null) { stack.push(cur.right); newCur.left = new TreeNode(cur.right.val); newStack.push(newCur.left); } if (cur.left != null) { stack.push(cur.left); newCur.right = new TreeNode(cur.left.val); newStack.push(newCur.right); } } return newRoot; }