JavaScript实现树结构(二)

本文详细介绍了如何使用JavaScript实现二叉搜索树,包括插入、查找、遍历(先序、中序、后序)和删除操作。文章还讨论了二叉搜索树的平衡性及其在非平衡状态下的性能问题,提及了AVL树和红黑树。
摘要由CSDN通过智能技术生成

JavaScript实现树结构(二)

一、二叉搜索树的封装

二叉树搜索树的基本属性

如图所示:二叉搜索树有四个最基本的属性:指向节点的(root),节点中的(key)、左指针(right)、右指针(right)。

image-20200301162706755

所以,二叉搜索树中除了定义root属性外,还应定义一个节点内部类,里面包含每个节点中的left、right和key三个属性:

    //封装二叉搜索树
    function BinarySearchTree(){

      //节点内部类
      function Node(key){
        this.key = key
        this.left = null
        this.right = null
      }

      //属性
      this.root = null
  }

 

二叉搜索树的常见操作:

  • insert(key):向树中插入一个新的键;
  • search(key):在树中查找一个键,如果节点存在,则返回true;如果不存在,则返回false;
  • inOrderTraverse:通过中序遍历方式遍历所有节点;
  • preOrderTraverse:通过先序遍历方式遍历所有节点;
  • postOrderTraverse:通过后序遍历方式遍历所有节点;
  • min:返回树中最小的值/键;
  • max:返回树中最大的值/键;
  • remove(key):从树中移除某个键;

1.插入数据

实现思路:

image-20200301191640632

 

 

 

  • 首先根据传入的key创建节点对象;
  • 然后判断根节点是否存在,不存在时通过:this.root = newNode,直接把新节点作为二叉搜索树的根节点。
  • 若存在根节点则重新定义一个内部方法insertNode()用于查找插入点。
         //insert方法:对外向用户暴露的方法
          BinarySearchTree.prototype.insert = function(key){
            //1.根据key创建节点
            let newNode = new Node(key)
              
            //2.判断根节点是否存在
            if (this.root == null) {
              this.root = newNode
              //根节点存在时
            }else {
              this.insertNode(this.root, newNode)
            }
          }
    
    

    内部方法insertNode()的实现思路:

    根据比较传入的两个节点,一直查找新节点适合插入的位置,直到成功插入新节点为止。

    当newNode.key < node.key向左查找:

  • 情况1:当node无左子节点时,直接插入:

  • 情况2:当node有左子节点时,递归调用insertNode(),直到遇到无左子节点成功插入newNode后,不再符合该情况,也就不再调用insertNode(),递归停止。

    当newNode.key >= node.key向右查找,与向左查找类似:

  • 情况1:当node无右子节点时,直接插入:

  • 情况2:当node有右子节点时,依然递归调用insertNode(),直到遇到传入insertNode方法的node无右子节点成功插入newNode为止:

    insertNode()代码实现:

          //内部使用的insertNode方法:用于比较节点从左边插入还是右边插入
          BinarySearchTree.prototype.insertNode = function(node, newNode){
            //当newNode.key < node.key向左查找
    /*----------------------分支1:向左查找--------------------------*/      
            if(newNode.key < node.key){
              //情况1:node无左子节点,直接插入
    /*----------------------分支1.1--------------------------*/
              if (node.left == null) {
                node.left = newNode
              //情况2:node有左子节点,递归调用insertNode(),直到遇到无左子节点成功插入newNode后,不再符合该情况,也就不再调用insertNode(),递归停止。
    /*----------------------分支1.2--------------------------*/
              }else{
                this.insertNode(node.left, newNode)
              }
            //当newNode.key >= node.key向右查找
    /*-----------------------分支2:向右查找--------------------------*/        
            }else{
              //情况1:node无右子节点,直接插入
    /*-----------------------分支2.1--------------------------*/ 
              if(node.right == null){
                node.right == newNode
              //情况2:node有右子节点,依然递归调用insertNode(),直到遇到无右子节点成功插入newNode为止
    /*-----------------------分支2.2--------------------------*/ 
              }else{
                this.insertNode(node.right, newNode)
              }
            }
          }
    

    过程详解:

    为了更好理解以下列二叉搜索树为例:

     

    image-20200301193104003

想要上述的二叉搜索树(蓝色)中插入数据10:

  • 先把key = 10 传入insert方法,由于存在根节点 9,所以直接调用insetNode方法,传入的参数:node = 9,newNode = 10;
  • 由于10 > 9,进入分支2,向右查找适合插入的位置;
  • 由于根节点 9 的右子节点存在且为 13 ,所以进入分支2.2,递归调用insertNode方法,传入的参数:node = 13,newNode = 10;
  • 由于 10 < 13 ,进入分支1,向左查找适合插入的位置;
  • 由于父节点 13 的左子节点存在且为11,所以进入分支1.2,递归调用insertNode方法,传入的参数:node = 11,newNode = 10;
  • 由于 10 < 11,进入分支1,向左查找适合插入的位置;
  • 由于父节点 11 的左子节点不存在,所以进入分支1.1,成功插入节点 10 。由于不符合分支1.2的条件所以不会继续调用insertNode方法,递归停止。

测试代码:

    //测试代码
    //1.创建BinarySearchTree
    let bst = new BinarySearchTree()

    //2.插入数据
    bst.insert(11);
    bst.insert(7);
    bst.insert(15);
    bst.insert(5);
    bst.insert(9);
	console.log(bst);

 

应得到下图所示的二叉搜索树:

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值