[路飞]_前端学数据结构-二叉树

290 阅读2分钟

「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

树的概念

图片.png

  • 节点:每一个元素
  • 边:从父节点到子节点的连线
  • 度:节点拥有的子元素,1节点的度为3,5节点的度为0
  • 兄弟节点:父节点相同的节点,如2,3,4
  • 叶子节点:度为0的节点,5,6,7
  • 树的深度:树的最大层数,图中的深度为3

二叉树

数.png

二叉树的特点

  • 二叉树是一种特殊的树形结构,每个节点度最多为2
  • 度为0的节点比度为2的节点多1个

二叉树的遍历

二叉树.png

  • 前序遍历:124536
  • 中序遍历:425136
  • 后序遍历:452631

几种特殊二叉树

  • 完全二叉树 Complete Binary Tree 除了最后一层之外的其他每一层都被完全填充,并且所有结点都保持向左对齐。 完全二叉树.png

  • 满二叉树 Full/Strictly Binary Tree 除了叶子结点之外的每一个结点都有两个孩子结点。 满二叉树.png

  • 完美二叉树 Perfect Binary Tree 除了叶子结点之外的每一个结点都有两个孩子,每一层(当然包含最后一层)都被完全填充。 完美二叉树.png

二叉树的作用

  • 理解高级数据结构的基础 理解高级数据结构的基础.png

  • 练习递归技巧的最佳选择 练习递归技巧的最佳选择.png

力扣算法练习题

/**
 * @param {TreeNode} root
 * @return {number[]}
 */

var preorderTraversal = function (root) {
  var ans = []

  preorder(root, ans)

  return ans
};
var preorder = function (root, ans) {
  if (!root) return // 边界条件
  // 前序遍历的顺序 根左右
  ans.push(root.val) // 根
  if (root.left) preorder(root.left, ans) // 递归左子树
  if (root.right) preorder(root.right, ans) // 递归右子树
}

226. 翻转二叉树

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {TreeNode}
 */
var invertTree = function(root) {
  if(!root) return null
  if(root.left || root.right) [root.left, root.right] = [root.right, root.left]
  invertTree(root.left)
  invertTree(root.right)
  return root
};

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function (preorder, inorder) {
  /**
   * @param {Number} pStart 前序开始点
   * @param {Number} pEnd   前序结束点
   * @param {Number} iStart 后序开始点
   * @param {Number} iEnd   后序结束点
   * @return {TreeNode}
   */
  var helper = function (pStart, pEnd, iStart, iEnd) {
    // 边界
    if(pStart > pEnd) return null
    var rootVal = preorder[pStart]
    // 在中序遍历中找到root.val的位置,左边为root.left,右边为root.right
    var mid = inorder.indexOf(rootVal)
    // 左子树长度
    var leftNum = mid - iStart 
    var root = new TreeNode(rootVal)
    root.left = helper(pStart + 1, pStart + leftNum, iStart, mid - 1)
    root.right = helper(pStart + leftNum + 1, pEnd, mid + 1, iEnd)
    return root
  }

  return helper(0, preorder.length - 1, 0, inorder.length - 1)
};

110. 平衡二叉树

/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function(root) {
    if(!root) return true
    return Math.abs(getHeight(root.left) - getHeight(root.right)) <= 1 
        && isBalanced(root.left) && isBalanced(root.right)
};
function getHeight(root) {
    if(!root) return 0
    return Math.max(getHeight(root.left), getHeight(root.right)) + 1
}

-- end --