【力扣】104. 二叉树的最大深度-及二叉树的遍历方式
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) {
val = x;
}
}
解法1:递归
public int maxDepth(TreeNode root) {
if (root == null){
return 0;
}
return Math.max(maxDepth(root.left),maxDepth(root.right)) + 1;
}
借此学习下二叉树的遍历方法:
二叉树有两种遍历方式,第一种是深度优先遍历算法,深度优先又分为前序遍历、中序遍历、后序遍历,第二种是广度优先遍历算法,也就是层次遍历
前序遍历:1 2 4 5 7 8 3 6
中序遍历:4 2 7 5 8 1 3 6
后序遍历:4 7 8 5 2 6 3 1
层次遍历:1 2 3 4 5 6 7 8
深度优先:
深度优先中的前序遍历:根结点 ---> 左子树 ---> 右子树
/** * 二叉树的深度优先遍历算法中的前序遍历 (递归) */ public List preOrder(TreeNode root) { if (root == null){ return null; } List<Integer> list = new ArrayList<>(); search(list,root); return list; } public void search(List<Integer> list,TreeNode root){ if (root != null){ list.add(root.val); search(list,root.left); search(list,root.right); } }
/** * 二叉树的深度优先遍历算法中的前序遍历 使用栈 * */ public List preOrderUseStack(TreeNode root) { if (root == null){ return null; } List<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack(); //也可以用栈实现 栈的特性是先进后出 stack.push(root); //若栈不空 while(!stack.isEmpty()){ //取出响应的节点 TreeNode node=stack.pop(); list.add(node.val); //考虑到先进后出的特性,所以先放右子节点 if(node.right!=null){ stack.push(node.right); } if(node.left!=null){ stack.push(node.left); } } return list; }
深度优先中的中序遍历:左子树 --->根结点 ---> 右子树
/** * 中序遍历 */ public List centerOrderUseStack(TreeNode root) { if (root == null){ return null; } List<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack(); //也可以用栈实现 栈的特性是先进后出 TreeNode currentNode = root; //若栈不空 while(currentNode != null || !stack.isEmpty()){ while(currentNode != null){ stack.push(currentNode); currentNode = currentNode.left; } //取出响应的节点 currentNode=stack.pop(); list.add(currentNode.val); currentNode = currentNode.right; } return list; }
深度优先中的后序遍历:左子树---> 右子树 --->根结点
/** * 后序遍历,后序遍历的特殊点在于我们要最后获取到根节点 还是很复杂的!!!!!! */ public List afterWordUseStack(TreeNode root) { if (root == null){ return null; } List<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack(); //也可以用栈实现 栈的特性是先进后出 TreeNode currentNode = root; TreeNode rightNode = null; //若栈不空 while(currentNode != null || !stack.isEmpty()){ //一直循环到最左端的叶子结点(currentNode是null) while(currentNode != null){ stack.push(currentNode); currentNode = currentNode.left; } //取出相应的节点 currentNode=stack.pop(); //若右节点是空,或者 当前节点的右节点为右节点 这样循环完成可以得到currentNode 父节点 while(currentNode.right == null || currentNode.right == rightNode){ list.add(currentNode.val); rightNode = currentNode; // 设置右节点为当前节点 if (stack.isEmpty()){ return list; } currentNode=stack.pop(); } stack.push(currentNode); //还有右结点没有遍历 currentNode = currentNode.right; } return list; }
后序遍历的更方便理解的一种方式(上面那种写完之后我都不记得了):
/** * 后序遍历,后序遍历的特殊点在于我们要最后获取到根节点 还是很复杂的!!!!!! */ public List afterWordUseStackEasy(TreeNode root) { if (root == null){ return null; } List<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack(); //也可以用栈实现 栈的特性是先进后出 TreeNode currentNode = null; TreeNode preNode = null; stack.push(root); //若栈不空 while(!stack.isEmpty()){ currentNode = stack.peek(); if ((currentNode.left == null && currentNode.right == null) || (preNode != null && (preNode == currentNode.left || preNode == currentNode.right))){ stack.pop(); list.add(currentNode.val); preNode = currentNode; } else { if (currentNode.right != null){ stack.push(currentNode.right); } if (currentNode.left != null){ stack.push(currentNode.left); } } } return list; }
广度优先:
/** * 广度优先遍历 又称层级遍历 需要借助数据结构 : 队列 */ public List spanUseStack(TreeNode root) { if (root == null){ return null; } //队列的特性为:先进先出 ArrayDeque<TreeNode> deque = new ArrayDeque<TreeNode>(); List<Integer> list = new ArrayList<>(); deque.add(root); while(!deque.isEmpty()){ TreeNode current = deque.remove(); list.add(current.val); if (current.left != null){ deque.add(current.left); } if (current.right != null){ deque.add(current.right); } } return list; }
二叉树层级遍历(打印层级):
public Node connect(Node root) { if(root == null){ return root; } Deque<Node> deque = new LinkedList<Node>(); deque.offer(root); int count = 0; while(!deque.isEmpty()){ count = deque.size(); Node pre = null; while(count > 0){ Node node = deque.remove(); node.next = pre; pre=node; if(node.right != null){ deque.offer(node.right); } if(node.left != null){ deque.offer(node.left); } count--; } } return root; }
一个入行不久的Java开发,越学习越感觉知识太多,自身了解太少,只能不断追寻