126 阅读2分钟

概念

二叉树是另一种树型结构,它的特点是每个结点至多只有两颗子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。

创建二叉树

leetcode98

应用场景

据说查找非常快

特征

  • 节点的左子树只包含小于当前节点的数。
  • 节点的右子树只包含大于当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

创建二叉搜索树

image.png 将数组依次遍历,从顶点开始,大于顶点的放右边,小于顶点的放左边。可以看到[10,20]因为20比10大,所以放在顶点的右边。再看25,此时树为[10,20],25比10大在右边往下到20,因为25比20大所以放在20的右边。依次循环便可构建二叉搜索树。 JavaScript创建二叉搜索树代码

      class Node {
        constructor(val) {
          this.val = val;
          this.left = this.right = undefined;
        }
      }
      class Tree {
        constructor(data) {
          let root = new Node(data.shift());
          //遍历所有的数据,逐渐插入到当前这颗搜索树中去
          data.forEach((item) => {
            this.insert(root, item);
          });
          return root;
        }
        insert(node, data) {
          if (node.val > data) {
            if (node.left == undefined) {
              node.left = new Node(data);
            } else {
              this.insert(node.left, data);
            }
          } else {
            if (node.right === undefined) {
              node.right = new Node(data);
            } else {
              this.insert(node.right, data);
            }
          }
        }
    }
    // 使用
    let root = new Tree([2, 1, 3]);

查找

function getNode (data, node) {
  if (node) {
      if (data === node.val) {
          return node;
      } else if (data < node.data) {
          return getNode(data,node.left);
      } else {
          return getNode(data,node.right);
      }
  } else {
      return null;
  }
}
//使用
let arr = [10, 20, 25, 16, 6, 17, 11, 8, 5]
let root = new Tree(arr)
console.log(getNode(20, root))

遍历

前序:根左右;中序:左根右;后序:左右根

image.png 代码示例二叉树: IMG_20210918_083748.jpg

深度优先遍历

前序遍历

  let preorderTraversal = function (root, array = []) {
      if (root) {
        array.push(root.val);
        preorderTraversal(root.left, array);
        preorderTraversal(root.right, array);
      }
      return array;
    }
    let arr = [10, 20, 25, 16, 6, 17, 11, 8, 5]
    let res = []
    let root = new Tree(arr)
    console.log(preorderTraversal(root, res))//[10, 6, 5, 8, 20, 16, 11, 17, 25]

中序遍历

    let inorderTraversal = function (root, array = []) {
      if (root) {
        inorderTraversal(root.left, array);
        array.push(root.val);
        inorderTraversal(root.right, array);
      }
      return array;
    }

后序遍历

    let inorderTraversal = function (root, array = []) {
      if (root) {
        inorderTraversal(root.left, array);
        inorderTraversal(root.right, array);
        array.push(root.val);
      }
      return array;
    }

广度优先遍历

参考

function bfs (node) {
    let result = [];
    let queue = [];
    queue.push(node);
    while(queue.length) {
        node = queue.shift();
        result.push(node.value); 
        node.left && queue.push(node.left);
        node.right && queue.push(node.right);
    }
    return result;
}
bfs(tree);
//  [10, 6, 20, 5, 8, 16, 25, 11, 17]

题目

树的深度

leetcode

image.png 后序遍历(深度优先遍历)

var maxDepth = function(root) {
    if(!root) return 0
    return Math.max(maxDepth(root.left), maxDepth(root.right)) +  1
};