网站首页 文章专栏 算法一篇 —— 二叉树的各种玩法
二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个结点最多只能有两棵子树,且有左右之分。
二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树
二叉树又分为其他很多种类,比如平衡二叉树,二叉查找树,红黑树,B树,2-3树等,应用也很广泛,比如mysql的b+树,hashmap的红黑树,常见的算法题,简单的就是二叉树的三种遍历,分别用循环和递归写出,中等点的,二叉树构建,镜像二叉树,二叉树高度,二叉树层次遍历,合并/反转二叉树等,难点的就是直接红黑树。。。据说都成为字节面试必考题(手动狗头)
这些题虽然都做过,长时间不做,有点忘了,正好都复习下:
1, 开胃菜:二叉树前,中,后,层次遍历
// 前序遍历 public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); if (root == null) return res; Deque<TreeNode> deque = new ArrayDeque<>(); deque.push(root); while (!deque.isEmpty()){ TreeNode cur = deque.pop(); res.add(cur.val); if (cur.right != null) deque.push(cur.right); if (cur.left != null) deque.push(cur.left); } return res; } // 中序遍历 public List<Integer> inorderTraversal(TreeNode root) { List<Integer> list = new ArrayList<>(); if (root == null) return list; Deque<TreeNode> deque = new ArrayDeque<>(); TreeNode cur = root; while (cur != null || !deque.isEmpty()){ while (cur != null){ deque.push(cur); cur = cur.left; } cur = deque.pop(); list.add(cur.val); cur = cur.right; } return list; } // 后续遍历 public List<Integer> postorderTraversal(TreeNode root) { LinkedList<Integer> res = new LinkedList<>(); if (root == null) return res; Deque<TreeNode> deque = new ArrayDeque<>(); deque.push(root); while (!deque.isEmpty()){ TreeNode cur = deque.pop(); res.addFirst(cur.val); if (cur.left != null) deque.push(cur.left); if (cur.right != null) deque.push(cur.right); } return res; } /** * 二叉树的层次遍历 * 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) * * 例如: * 给定二叉树 [3,9,20,null,null,15,7], * * 3 * / \ * 9 20 * / \ * 15 7 * 返回其自底向上的层次遍历为: * * [ * [15,7], * [9,20], * [3] * ] */ public static List<List<Integer>> levelOrderBottom(TreeNode root) { LinkedList<List<Integer>> result = new LinkedList<>(); if (root == null) return result; Deque<TreeNode> deque = new ArrayDeque<>(); deque.offer(root); while (!deque.isEmpty()) { int size = deque.size(); List<Integer> list = new ArrayList<>(); for (int i = 0; i < size; i++) { TreeNode cur = deque.poll(); list.add(cur.val); if (cur.left != null) deque.offer(cur.left); if (cur.right != null) deque.offer(cur.right); } result.addFirst(list); } return result; }
继续,二叉树的各种反转,长度,判断
/** * 二叉树的最大深度 * 给定一个二叉树,找出其最大深度。 * * 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 * * 说明: 叶子节点是指没有子节点的节点 */ public static int maxDepth2(TreeNode root) { if (root == null) return 0; int left = maxDepth2(root.left); int right = maxDepth2(root.right); return Math.max(left,right) + 1; } /** * 合并二叉树 * 给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。 */ public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { if(t2 == null) return t1; if(t1 == null) return t2; t1.val += t2.val; t1.left = mergeTrees(t1.left,t2.left); t1.right = mergeTrees(t1.right,t2.right); return t1; } /** * 左叶子之和 * 计算给定二叉树的所有左叶子之和。 * * 示例: * * 3 * / \ * 9 20 * / \ * 15 7 * 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 * * 0 * / \ * 2 4 * / / \ * 1 3 -1 * / \ \ \ * 5 1 6 8 * * 返回5 */ public class SumOfLeftLeaves { int sum = 0; public int sumOfLeftLeaves(TreeNode root) { if (root == null) return 0; dfs(root); return sum; } private void dfs(TreeNode root) { if (root == null) return; if (root.left != null && root.left.left == null && root.left.right == null) { sum += root.left.val; } dfs(root.left); dfs(root.right); } } /** * 把二叉搜索树转换为累加树 * 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和。 * 例如: * * 输入: 原始二叉搜索树: * 5 * / \ * 2 13 * * 输出: 转换为累加树: * 18 * / \ * 20 13 */ public class ConvertBST { int sum = 0; /** * 思路要点:注意给的是二叉搜索树,如果给定的树是二叉搜索树,那么一定要从二叉搜索树的特征去思考 * 1. 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; * 2. 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值; * 3. 它的左、右子树也分别为二叉搜索树。 * 二叉搜索树的中序遍历是一个单调递增的有序序列 (重点!!) * * 每个节点都要加上比自己大的节点,那么可以从最大的开始遍历,累加遍历的结果,赋值给当前节点即可,也就是倒着中序遍历 * @param root * @return */ public TreeNode convertBST(TreeNode root) { if (root == null) return root; convertBST(root.right); sum += root.val; root.val = sum; convertBST(root.left); return root; } }
暂时就这么多,下周继续druid。。。
版权声明:本文由星尘阁原创出品,转载请注明出处!