「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」
二叉树简介
- 一种非常重要的数据结构
- 五种形态
- 空二叉树 = 没有根结点 + 没有子节点
- 只有根结点,没有子节点
- 根结点 + 左子树
- 根结点 + 右子树
- 完全二叉树 = 根结点 + 左子树 + 右子树
- 节点的度 <= 2
二叉树拥有特别好算的性质
- 第 i 层: 节点数 <= 2i - 1
- 深度为 h:节点数 <= 2h - 1
- n 个叶子节点 + m 个度为 2 的节点:n = m + 1
- 满二叉树 + n 个节点:深度 = log2n + 1
- 完全二叉树 + n 个节点:
- i = 1: 当前节点为根结点
- i > 1: 父节点编号 = i / 2
- 2i <= n: 左节点编号 = 2i
- 2i + 1 <= n: 右节点编号 = 2i + 1
二叉树的遍历
- 深度遍历(2年前在力扣刷的题,每道题都用去了半天的时间)
- 前序遍历 【 根 + 左 + 右 】
- 通过递归方法来进行二叉树的前序遍历
var preorderTraversal = function(root, arr=[]) { if(root) { arr.push(root.val) // 根 preorderTraversal(root.left, arr) // 左子树(递归) preorderTraversal(root.right, arr) // 右子树(递归) } return arr // 返回排好序的当前递归的节点 };- 通过迭代方法来进行二叉树的前序遍历
var preorderTraversal = function(root) { let result = [] // 定义排序数组 let stack = [] // 定义栈 let cur = root // 指定当前节点 while(cur || stack.length > 0) { // 当前节点为空 或 栈为空时,循环结束 while(cur) { result.push(cur.val) // 根的值 stack.push(cur) // 当前节点入栈 cur = cur.left // 指定左子树为下一次的循环的根结点 } cur = stack.pop() // 弹出栈 cur = cur.right // 指定当前节点为右节点 } return result // 返回最终的二叉树前序遍历的结果 }; - 中序遍历 【 左 + 根 + 右 】
- 通过递归方法来进行二叉树的中序遍历
var inorderTraversal = function(root, arr = []) { if (root) { inorderTraversal(root.left, arr) // 左子树(递归) arr.push(root.val) // 根 inorderTraversal(root.right, arr) // 右子树(递归) } return arr // 返回当前节点 };- 通过迭代方法来进行二叉树的中序遍历
var preorderTraversal = function(root) { let result = [] // 定义排序数组 let stack = [] // 定义栈 let cur = root while(cur || stack.length > 0) { while(cur) { // 左 result.push(cur.val) stack.push(cur) cur = cur.left } cur = stack.pop() // 弹出栈 cur = cur.right // 右 } return result }; - 后序遍历 【 左 + 右 + 根 】
- 同样可以用递归和迭代两种方法来进行排序
- 前序遍历 【 根 + 左 + 右 】
- 广度遍历
- 层序遍历 【 逐层 】
-
处理完一层再去处理下一层的数据
-
- 层序遍历 【 逐层 】
二叉树的性质和遍历方法,都是非常重要的,希望在算法方面有所发展的小伙伴一定要好好掌握呦,很多复杂的数据结构都是通过对二叉树的各种排序操作得来的。千万不要觉得它很简单,就不忽略呦!!!