数据结构和算法-树与二叉树

树形结构是一种非线性数据结构。
树中的每个部分称为结点,结点间存在分支结构与层次关系。
每个树型结构都有一个根节点。
根据结点之间的关系,也存在父节点、子节点、兄弟结点的概念。

不含子节点的结点称为叶结点。
在这里插入图片描述
子树:对某个结点与其后代结点的整体称呼。
由于存在父子关系,树中的结点形成多级结构,称为层级。
根节点层级为1,向下依次递增。
树中最深结点的层级称为树的高度。

二叉树

二叉树是树形结构中的一种,二叉树中的每个结点最多只能存在2个子节点。
左子节点、右子节点、左子树、右子树

满二叉树

二叉树的每层节点都达到最大值,称为满二叉树。

完全二叉树

二叉树的除最后一层外,每层结点都达到最大值,且最后一层结点都位于左侧,这种形式称为完全二叉树。满二叉树也属于完全二叉树。

前序遍历

/* var preorderTraversal = function(root) {
  // 用于存储遍历的结果
  const res = []
  // 设置函数用于进行递归遍历
  const preorder = (root) => {
    // 当前结点为空时,无需进行递归
    if (!root) {
      return
    }
    // 记录根节点值
    res.push(root.val)
    // 前序遍历左子树
    preorder(root.left)
    // 前序遍历右子树
    preorder(root.right)
  }
  preorder(root)
  return res
}; */

const preorderTraversal = function(root) {
  const res = []
  const stk = []
  while (root || stk.length) {
    while (root) {
      // 右子结点入栈
      stk.push(root.right)
      // 记录根节点
      res.push(root.val)
      // 下一步处理左子节点
      root = root.left
    }
    // 左子树处理完毕,将 stk 出栈,处理右子树
    root = stk.pop()
  }
  return res
}

二叉树的最大深度

前序遍历操作时使用的算法称为深度优先搜索算法(dfs)

/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxDepth = function(root) {
  if (!root) {
    return 0
  }
  return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1
};

二叉树的层序遍历

广度优先搜索算法bfs,借助于队列

/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
  const res = []
  if (!root) {
      return res
  }
  // 声明队列用于存储后续数据
  const q = []
  q.push(root)

  // 遍历队列
  while (q.length !== 0) {
      // 针对本轮操作,创建一个新的二维数组
      res.push([])
      let len = q.length
      for (let i = 0; i < len; i++) {
          // 将本次操作的结点出队
          const node = q.shift()
          res[res.length - 1].push(node.val)
          // 检测是否存在左右子结点,如果有,入队即可
          if (node.left) {
              q.push(node.left)
          }
          if (node.right) {
              q.push(node.right)
          }
      }
  }
  return res
};

二叉搜索树

二叉搜索树是一种特殊的二叉树,简称BST。
左子树的结点小于根节点,右子树的结点大于根节点。
子树也为二叉搜索树。

// 二叉搜索树
/* var isValidBST = function(root) {
  // 通过一个辅助函数来统一设置左右子树的比较
  return helper(root, -Infinity, Infinity);
};

const helper = (root, lower, upper) => {
  if (root === null) {
    return true
  }
	// 当前节点值超出边界,说明二叉树为非 BST
  if (root.val <= lower || root.val >= upper) {
    return false;
  }
  // 否则,递归处理左右子节点,并更新大小范围
  // 同时根据左右子节点的返回值进行返回,只有全部递归结果均为 true, 才说明二叉树为 BST
  return helper(root.left, lower, root.val) && helper(root.right, root.val, upper);
} */

//第二种

/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isValidBST = function(root) {
  let stk = []
  // 用于记录上一次取得的节点值,BST 中这个值应小于当前节点
  // 设置默认值为 -Infinity 避免对比较结果产生干扰
  let oldNode = -Infinity

  while (root || stk.length) {
    while (root) {
      stk.push(root) 
      root = root.left
    }
    root = stk.pop()
    // 如果任意节点比上个节点值小,说明二叉树不是 BST
    if (root.val <= oldNode) {
      return false
    }
    // 通过比较,记录当前节点值
    oldNode = root.val
    root = root.right
  }
  return true
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微星星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值