什么是树

它是一种分层数据的抽象模型。前端中常见的树包括:DOM,级联选择,树形控件等
JS中没有树结构,但是可以用Object和Array构建树。如下:

  1. {
  2. label: 'aa',
  3. value: 'vv',
  4. children: [{
  5. label: 'bb',
  6. value: 'bb',
  7. }]
  8. }

常用操作

深度/广度优先遍历,先中后序遍历

深度遍历与广度优先遍历

深度优先遍历: 尽可能搜索树的分支

image.png

  • 访问根节点
  • 对根节点的children挨个进行深度优先遍历 ```javascript const tree ={ val: ‘a’, children: [{ val: ‘b’, },{ val: ‘c’, }] }

const dfs = (root) =>{ console.log(‘val’, root.val) root.children.forEach(item=>{ def(item) }) }

  1. <a name="CeazY"></a>
  2. #### 广度优先遍历:先访问离根节点最近的节点
  3. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/266511/1646837959811-ad52e4b3-aff4-440c-904e-5991ec84abbb.png#clientId=udfd70cb2-5ca8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=453&id=u48871a0a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=906&originWidth=492&originalType=binary&ratio=1&rotation=0&showTitle=false&size=177441&status=done&style=none&taskId=uda731b25-e606-4fbb-9548-dadbb8fbe51&title=&width=246)
  4. - 新建队列,把根节点入队
  5. - 把队头出队并访问
  6. - 把对头的children挨个入队
  7. - 重复第二,第三步,知道队列为空
  8. ```javascript
  9. const bfs =(root)=>{
  10. const q = [root]
  11. while(q.length > 0) {
  12. const n = q.shift()
  13. console.log('n', n.val)
  14. n.children.forEach(child=>{
  15. q.push(child)
  16. })
  17. }
  18. }

二叉树的先中后序遍历(递归版)

树中每个节点最多只能有两个子节点

  1. const binaryTree = {
  2. val: 1,
  3. left: {
  4. val: 2,
  5. left: null,
  6. right: null
  7. },
  8. right: {
  9. val: 3,
  10. left: null,
  11. right: null
  12. },
  13. }

先序遍历

  1. 访问根节点
  2. 对根节点的左子树进行先序遍历
  3. 对根节点的右子树进行先序遍历

image.png

  1. const preOrder = (root) =>{
  2. if(!root) return
  3. console.log(root.val)
  4. preOrder(root.left)
  5. preOrder(root.right)
  6. }

中序遍历

  1. 对根节点的左子树进行中序遍历
  2. 访问根节点
  3. 对根节点的右子树进行中序遍历

image.png

  1. const inOrder = (root) =>{
  2. if(!root) return
  3. inOrder(root.left)
  4. console.log(root.val)
  5. inOrder(root.right)
  6. }

后序遍历

  1. 对根节点的左子树进行后序遍历
  2. 对根节点的右子树进行后序遍历
  3. 访问根节点

image.png

  1. const postOrder = (root) =>{
  2. if(!root) return
  3. postOrder(root.left)
  4. postOrder(root.right)
  5. console.log(root.val)
  6. }


二叉树最大深度(leetcode 104)

  • 新建变量,记录最大深度
  • 深度遍历二叉树,并记录每个节点层级,同时不断刷新最大深度这个变量
  • 返回变量
    1. /**
    2. * Definition for a binary tree node.
    3. * function TreeNode(val, left, right) {
    4. * this.val = (val===undefined ? 0 : val)
    5. * this.left = (left===undefined ? null : left)
    6. * this.right = (right===undefined ? null : right)
    7. * }
    8. */
    9. /**
    10. * @param {TreeNode} root
    11. * @return {number}
    12. */
    13. var maxDepth = function(root) {
    14. let max = 0
    15. function dfs(data, level) {
    16. if(!data) return
    17. // 优化:判断是叶子节点
    18. if(!data.left && !data.right){
    19. max = Math.max(max, level)
    20. }
    21. dfs(data.left, level + 1)
    22. dfs(data.right, level + 1)
    23. }
    24. dfs(root, 1)
    25. return max
    26. };

二叉树最小深度(leetcode 111)

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. * @return {number}
  12. */
  13. var minDepth = function(root) {
  14. if(!root) return 0;
  15. const stack = [[root, 1]]
  16. while(stack.length){
  17. const [n, l] = stack.shift()
  18. if(!n.left && !n.right){
  19. return l
  20. }
  21. n.left && stack.push([n.left, l+1])
  22. n.right && stack.push([n.right, l+1])
  23. }
  24. };

二叉树层序遍历(leetcode 102)

  1. /**
  2. * Definition for a binary tree node.
  3. * function TreeNode(val, left, right) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.left = (left===undefined ? null : left)
  6. * this.right = (right===undefined ? null : right)
  7. * }
  8. */
  9. /**
  10. * @param {TreeNode} root
  11. * @return {number[][]}
  12. */
  13. var levelOrder = function(root) {
  14. if(!root || root.length === 0) return []
  15. const stack = [[root, 0]]
  16. const res = []
  17. while(stack.length){
  18. const [n, level] = stack.shift()
  19. res[level] = res[level] || []
  20. res[level].push(n.val)
  21. n.left && stack.push([n.left, level+1])
  22. n.right && stack.push([n.right, level+1])
  23. }
  24. return res
  25. };