【WEB前端开发】JavaScript二叉树(binary search tree)的详细介绍

电脑杂谈  发布时间:2020-07-09 22:18:26  来源:网络整理

二叉查找树 二叉排序树_树与二叉树的转换代码_排序二叉树的建立

本文为您详细介绍了JavaScript二进制树(二进制搜索树). 它具有一定的参考价值. 有需要的朋友可以参考它,希望对您有所帮助.

可能有些人没有读我在上一篇文章中写的二进制叉,所以在这里我复制了二进制树的基本概念. 如果已阅读过,则可以忽略先前对二叉树基本概念的介绍. 如果数据结构不清楚,最好看看我写的链表的js数据结构

二叉树(Binary Tree)是一种树结构. 其特征是每个节点最多具有两个分支节点. 二叉树通常由根节点,分支节点和叶节点组成. 每个分支节点通常称为子树.

常用条款

在二叉树中,我们经常使用父节点和子节点来描述,例如,图中的2是6和3的父节点,否则6和3是2个子节点

在二叉树的第i层,最多有2 ^ i-1个节点

深度为k的二叉树最多具有2 ^ k-1个节点

二叉查找树 二叉排序树_树与二叉树的转换代码_排序二叉树的建立

对于任何二叉树T,如果点的总和为n0且度为2的节点数(子树的数量为2)为n2,则n0 = n2 + 1

二叉树分为完整的二叉树(完整的二叉树)和完整的二叉树(完整的二叉树)

二进制搜索树满足以下属性:

让我们举个例子来深入了解以下内容

一组数据: 12、4、18、1、8、16、20

从下图可以看到,左图满足二叉树的性质. 每个左子节点均小于父节点,右子节点均大于其父节点,左子树节点均小于根节点. 右子树的节点大于根节点

二叉查找树 二叉排序树_树与二叉树的转换代码_排序二叉树的建立

二分搜索树的主要操作:

从下图可以看到,二叉搜索树的节点通常包含4个字段二叉查找树 二叉排序树,即数据元素,由指向其左右节点的指针和指向父节点的指针组成. 这种存储结构通常称为“三叉列表”

使用代码初始化二进制搜索树的节点:

    class BinaryTreeNode {
        constructor(key, value){
            this.parent = null;
            this.left = null;
            this.right = null;
            this.key = key;
            this.value = value;
        }
    }

接下来,我们使用代码初始化二进制搜索树

    class BinarySearchTree {
        constructor() {
            this.root = null;
        }
    }

    static createNode(key, value) {
        return new BinarySearchTree(key, value);
    }

树与二叉树的转换代码_排序二叉树的建立_二叉查找树 二叉排序树

看下面的图片,我们要插入的节点是13,它插入的具体步骤:

与根节点12相比,它大于12,因此我们确定此节点已插入到正确的子树中

如果根节点右边已经有一个节点,则与该节点18进行比较二叉查找树 二叉排序树,结果要比之前的18个左侧节点要查找位置小

并且18的左节点已经有一个节点,因此继续与此节点进行比较,结果小于16

仅16个节点的左节点为空(left = null),因此将13个节点插入了16个节点的左节点

通过上面的描述,让我们看看如何编写代码

    insert(node){
        let p = this.root;
        let tail = this.root;
        
        // 循环遍历,去找到对应的位置
        while(tail) {
            p = tail;
            // 要插入的节点key比当前节点小
            if (node.key < tail.key){
                tail.left = tail.left;
            }
            // 要插入的节点key比当前节点大
            else {
                tail.right = tail.right;
            }
        }
        
        // 没有根节点,则直接作为根节点插入
        if(!p) {
            this.root = node;
            return;
        }
        
        // p是最后一个节点,也就是我们要插入的位置的父节点
        // 比父节点大则往右边插入
        if(p.key < node.key){
            p.right = node;
        }
        // 比父节点小则往左边插入
        else {
            p.left = node;
        }
        
        // 指向父节点
        node.parent = p;
    }

树与二叉树的转换代码_二叉查找树 二叉排序树_排序二叉树的建立

搜索非常简单. 实际上,它与插入有很大不同. 不要调用左右节点的大小,然后向下看

    search(key) {
        let p = this.root;
        if(!p) {
            return;
        }
        
        while(p && p.key !== key){
            if(p.key<key){
                p = p.right;
            }else{
                p = p.left;
            }
        }
        
        return p;
    }

最常用的是中阶遍历,因为中阶遍历可以获得排序列表,这就是为什么使用二叉搜索树进行排序的原因

根据以上对中阶遍历的解释,代码变得非常简单,这是一个递归过程,而递归停止的条件是该节点为空

    transverse() {
        return this._transverse(this.root);
    }
    
    *_transverse(node){
        if(!node){
            return;
        }
        yield* this._transverse(node.left);
        yield node;
        yield* this._transverse(node.right)
    }

看看上面的图片,让我们简单地看一下,首先访问左边的节点4,然后访问12,然后再访问右边的节点18,所以输出只是12、4、8

补充: 在此位置使用了Generator,因此它返回一个迭代器. 您可以通过以下方式获得有序数组,前提是已经有插入的节点

   const tree = new BinaryTree();
   //...中间省略插入过程
    
   // 这样就返回了一个有序的数组 
   var arr = [...tree.transverse()].map(item=>item.key);

class BinaryTreeNode {
  constructor(key, value) {
    // 指向父节点
    this.p = null;
    // 左节点
    this.left = null;
    // 右节点
    this.right = null;
    // 键
    this.key = key;
    // 值
    this.value = value;
  }
}
class BinaryTree {
  constructor() {
    this.root = null;
  }
  static createNode(key, value) {
    return new BinaryTreeNode(key, value);
  }
  search(key) {
    let p = this.root;
    if (!p) {
      return;
    }
    while (p && p.key !== key) {
      if (p.key < key) {
        p = p.right;
      } else {
        p = p.left;
      }
    }
    return p;
  }
  insert(node) {
    // 尾指针的父节点指针
    let p = this.root;
    // 尾指针
    let tail = this.root;
    while (tail) {
      p = tail;
      if (node.key < tail.key) {
        tail = tail.left;
      } else {
        tail = tail.right;
      }
    }
    if (!p) {
      this.root = node;
      return;
    }
    // 插入
    if (p.key < node.key) {
      p.right = node;
    } else {
      p.left = node;
    }
    node.p = p;
  }
  transverse() {
    return this.__transverse(this.root);
  }
  *__transverse(node) {
    if (!node) {
      return;
    }
    yield* this.__transverse(node.left);
    yield node;
    yield* this.__transverse(node.right);
  }
}

二进制搜索树完成. 实际上,这与链接列表非常相似. 它仍然操作一些指针. 由于它被称为搜索树,因此主要用于左搜索. 也有排序. 现在,如果您已大致了解二进制搜索树中的最大值和最小值,也非常方便.


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-274595-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 杨希道
        杨希道

        谁让你那么遭人恨呢

      • 克比
        克比

        看看能把小米骂倒吗

      • 樊珣
        樊珣

        这也是后来的战列舰大战通常采取的战法

      热点图片
      拼命载入中...