常用数据结构(五)树

树型数据结构在前端中很常见,比如(虚拟)DOM 树、抽象语法分析树。

总结起来,树就是有限节点组成一个具有层次关系的集合,因为它看起来非常像一棵倒着生长的树,根朝上叶朝下,所以命名为“树”。

树根据结构不同,可以分为很多类,例如:

  1. 有序树(树中任意节点,比如,点的子节点之间有顺序关系)
  2. 二叉树(每个节点最多有 2 个子树)
  3. 满二叉树(除最后一层所有节点都有两个子节点)等

其中,二叉树是最简单且最基础的树。说它简单,是因为每个节点至多包含两个子节点;说它基础,是因为二叉树可以延伸出一些子类,例如:

  1. 二叉搜索树(BST)
  2. 平衡二叉搜索树(AVL)
  3. 红黑树(R/B Tree)等

所以我们重点分析二叉树的查询操作——遍历。

树的遍历操作分为两类:深度遍历广度遍历,其中深度遍历按照遍历根节点的顺序不同又可以分为 3 类:先序遍历、中序遍历和后序遍历。它们的遍历顺序如下:

  • 先序遍历,根节点→左子树→右子树
  • 中序遍历,左子树→根节点→右子树
  • 后序遍历,左子树→右子树→根节点
  • 广度遍历,逐层从左至右访问

实现深度遍历最简单的方式就是通过递归,下面是具体代码:

// 先序遍历,根->左->右
function preOrder(node, result=[]) {
  if (!node) return
  result.push(node.value);
  preOrder(node.left, result);
  preOrder(node.right, result);
  return result;
}

// 中序遍历,左->根->右
function inOrder(node, result=[]) {
  if (!node) return
  inOrder(node.left, result);
  result.push(node.value);
  inOrder(node.right, result);
  return result;
}

// 后序遍历,左->右->根
function postOrder(node, result=[]) {
  if (!node) return
  postOrder(node.left, result);
  postOrder(node.right, result);
  result.push(node.value);
  return result;
}

广度优先遍历的实现会稍稍复杂一些,因为每次访问节点时都要回溯到上一层的父节点,通过其指针进行访问。

但每一层都是从左至右的遍历顺序,这种操作方式很符合队列的先进先出原则,所以可以通过队列来缓存遍历的节点,具体代码如下所示:

function breadthOrder(node) {
  if(!node) return
  var result = []
  var queue = []
  queue.push(node)
  while(queue.length !== 0) {
    node = queue.shift()
    result.push(node.value)
    if(node.left) queue.push(node.left)
    if (node.right) queue.push(node.right)
  }
  return result
}

参考:《前端高手进阶》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值