zoukankan      html  css  js  c++  java
  • js二叉树

    二叉树的意思就是说:每个节点不能多于有两个儿子

    • 一棵树至少会有一个节点(根节点)
    • 树由节点组成,而节点的定义就是:一个数据、两个指针(如果有节点就指向节点、没有节点就指向null)
    • 因此,我们定义树的时候往往是**->定义节点->节点连接起来就成了树**,

    二叉树中还有一种特殊的二叉树:二叉查找树(binary search tree)

    • 定义:当前根节点的左边全部比根节点小,当前根节点的右边全部比根节点大。
      • 明眼人可以看出,这对我们来找一个数是非常方便快捷的

    使用js创建一个二叉查找树

    function Node(key) {
      this.key = key;
      this.left = null;
      this.right = null;
    }
    function BinarySearchTree() {
      this.root = null;
    }
    // 查询树排序插入
    function insertNode(node, newNode) {
      // 如果新节点值小于当前节点值,则插入左子节点
      if (newNode.key < node.key) {
        if (node.left === null) {
          node.left = newNode;
        } else {
          insertNode(node.left, newNode);
        }
      } else {
        // 如果新节点值大于当前节点值,则插入右子节点
        if (node.right === null) {
          node.right = newNode;
        } else {
          insertNode(node.right, newNode);
        }
      }
    }
    // 插入
    BinarySearchTree.prototype.insert = function (key) {
      let newNode = new Node(key);
      if (this.root === null) {
        this.root = newNode;
      } else {
        insertNode(this.root, newNode);
      }
    }
    
    let tree = new BinarySearchTree()
    tree.insert(19)
    tree.insert(10)
    tree.insert(20)
    tree.insert(23)
    tree.insert(1)
    tree.insert(18)
    console.log(tree)

    打印出来的效果

     创建的二叉树结构就是下图所示

    遍历二叉树

    二叉树遍历有三种方式

    • 先序遍历
      • 先访问根节点,然后访问左节点,最后访问右节点(根->左->右)
    • 中序遍历
      • 先访问左节点,然后访问根节点,最后访问右节点(左->根->右)
    • 后序遍历
      • 先访问左节点,然后访问右节点,最后访问根节点(左->右->根)

    以上面的二叉树为例:

    • 如果是先序遍历19->10->1->18->20->23
    • 如果是中序遍历1->10->18->19->20->23
    • 如果是后序遍历1->18->10->23->20->19
    let tree = new BinarySearchTree()
    tree.insert(19)
    tree.insert(10)
    tree.insert(20)
    tree.insert(23)
    tree.insert(1)
    tree.insert(18)
    // console.log(tree)
    // 先序遍历
    function preTraverseBTree(treeNode) {
      if(treeNode !== null) {
        console.log(treeNode.key)
        preTraverseBTree(treeNode.left)
        preTraverseBTree(treeNode.right)
      }
    }
    // 中序遍历
    function inTraverseBTree(treeNode) {
      if(treeNode !== null) {
        inTraverseBTree(treeNode.left)
        console.log(treeNode.key)
        inTraverseBTree(treeNode.right)
      }
    }
    // 后序遍历
    function afterTraverseBTree(treeNode) {
      if(treeNode !== null) {
        afterTraverseBTree(treeNode.left)
        afterTraverseBTree(treeNode.right)
        console.log(treeNode.key)
      }
    }
    console.log('先序遍历')
    preTraverseBTree(tree.root)
    console.log('中序遍历')
    inTraverseBTree(tree.root)
    console.log('后序遍历')
    afterTraverseBTree(tree.root)

    无论先中后遍历,每个节点的遍历如果访问有孩子的节点,先处理孩子的(逻辑是一样的)

    • 因此我们很容易想到递归
    • 递归的出口就是:当没有子节点了,就返回
  • 相关阅读:
    组合模式
    HashMap,ArrayList扩容
    Maven入门使用(一)
    OutputStreamWriter API 以及源码解读
    java.io.BufferedWriter API 以及源码解读
    java.io.writer API 以及 源码解读
    自定义redis序列化工具
    策略模式
    Spring下redis的配置
    简单工厂模式
  • 原文地址:https://www.cnblogs.com/wangxirui/p/15380790.html
Copyright © 2011-2022 走看看