• 树数据结构:树是一种分层数据的数据模型
    树数据结构理解:位于树顶部的节点叫做根节点.它没有父节点.树中的每个元素都叫做节点,节点分为内部节点和外部节点.至少有一个子节点的节点称为内部节点.没有子元素的节点称为外部节点或叶节点.
    二叉树和二叉搜索树:二叉树中的节点最多只能有两个子节点:一个是左侧子节点,另一个是右侧子节点.二叉搜索树是二叉树的一种.但是只允许你在左侧节点存储(比父节点)小的值,在右侧节点存储(比父节点)大的值.
    个人理解:和链表一样我们将通过指针(引用)来表示节点之间的关系.在双向链表中,每个节点包含两个指针,一个指向下一个节点,另一个指向上一个节点.对于树,使用同样的方式(也是用两个指针),一个指向左侧子节点,另一个指向右侧子节点
    实现一个二叉搜索树
    class BinarySearchTree{
      constructor(compareFn = defaultCompare){
        this.root = null
        this.compareFn = compareFn
      }
    }

    先创建一个二叉搜索树节点

    class Node{
      constructor(key){
        this.key = key
        this.left = null
        this.right = null
      }
    }
    

      

    实现一个insertNode方法
    BinarySearchTree.prototype.insertNode = function(node,key){
      if(this.compareFn(node.key,key)===Compare.LESS_THAN){
        if(node.left == null){
          node.left = new Node(key)
        }else{
          this.insertNode(node.left,key)
        }
      }else{
        if(node.right == null){
          node.right = new Node(key)
        }else{
          this.insertNode(node.right,key)
        }
      }
    }

    实现一个insert方法

    BinarySearchTree.prototype.insert = function(key){
      if(this.root==null){
        this.root = new Node(key)
      }else{
        this.insertNode(this.root,key)
      }
    }

    定义一个回调函数

    function cnFn(param){
      console.log(param)
    }

    中序遍历:是一种上行顺序访问BST所有节点的遍历方式,也就是以从最小到最大的顺序访问所有节点,中序遍历的一种应用就是对树进行排序操作

    BinarySearchTree.prototype.inOrderTraverse = function(cb){
      this.inOrderTraverseNode(this.root,cb)
    }
     
    
    BinarySearchTree.prototype.inOrderTraverseNode = function(node,cb){
      if(node!=null){
        this.inOrderTraverseNode(node.left,cb)
        cb(node.key)
        this.inOrderTraverseNode(node.right,cb)
      }
    }

    先序遍历:是以优先于后代节点的顺序访问每个节点。先序遍历的一种应用是打印一个结构化文档

    BinarySearchTree.prototype.preOrderTraverse = function(cb){
      this.preOrderTraverseNode(this.root,cb)
    }
    
    BinarySearchTree.prototype.preOrderTraverseNode = function(node,cb){
      if(node!=null){
        cb(node.key)
        this.preOrderTraverseNode(node.left,cb)
        this.preOrderTraverseNode(node.right,cb)
      }
    }

    后序遍历:是先访问节点的后代节点在访问节点本身。后序遍历的一种应用是计算一个目录及其子目录中所有文件所占空间的小

    BinarySearchTree.prototype.postOrderTraverse = function(cb){
      this.postOrderTraverseNode(this.root,cb)
    }
    
    BinarySearchTree.prototype.postOrderTraverseNode = function(node,cb){
      if(node!=null){
        this.postOrderTraverseNode(node.left,cb)
        this.postOrderTraverseNode(node.right,cb)
        cb(node.key)
      }
    }
    /**
    * 搜索树中的值
    * 搜索最小值和最大值
    * 先实现获取到最小与最大节点,再使用min、max方法调用
    */
    BinarySearchTree.prototype.minNode = function(node){
      let current = node
      while(current!=null&&current.left!=null){
        current = current.left
      }
      return current
    }
     
    
    BinarySearchTree.prototype.maxNode = function(node){
      let current = node
      while(current!=null&&current.right!=null){
        current = current.right
      }
      return current
    }
     
    
    BinarySearchTree.prototype.min = function(){
      return this.minNode(this.root)
    }
     
    
    BinarySearchTree.prototype.max = function(){
      return this.maxNode(this.root)
    }
    /**
    * 先实现一个searchNode方法
    */
    BinarySearchTree.prototype.searchNode = function(node,key){
      if(node==null){
        return false
      }
      if(this.compareFn(key,node.key) === Compare.LESS_THAN){
        return this.searchNode(node.left,key)
      }else if(this.compareFn(key,node.key) === Compare.BIGGER_THAN){
        return this.searchNode(node.right,key)
      }else{
        return true
      }
    }
    /**
    * 搜索一个特定的值;返回值:布尔值
    */
    BinarySearchTree.prototype.search = function(key){
      return this.searchNode(this.root,key)
    }
    /**
    * 先实现一个removeNode方法;返回值:一个node节点对象
    */
    BinarySearchTree.prototype.removeNode = function(node,key){
      if(node==null){
        return null
      }
      if(this.compareFn(key,node.key) === Compare.LESS_THAN){
        node.left = this.removeNode(node.left,key)
        return node
      }else if(this.compareFn(key,node.key) === Compare.BIGGER_THAN){
        node.right = this.removeNode(node.right,key)
        return node
      }else{
        if(node.left == null && node.right == null){
          node = null
          return node
        }
        if(node.left == null){
          node = node.right
          return node
        }else if(node.right == null){
          node = node.left
          return node
        }
        let min = this.minNode(node.right)
        node.key = min.key
        node.right = this.removeNode(node.right,min.key)
        return node
      }
    }
    /**
    * 移除一个节点
    */
    BinarySearchTree.prototype.remove = function(key){
      this.root = this.removeNode(this.root,key)
    }
    

    AVL & 红黑树 

    未完待续...

  • 相关阅读:
    学习windows编程 day4 之视口和窗口
    学习windows编程 day4 之 映射模式
    学习windows编程 day4 之 盯裆猫
    Android自动化测试(UiAutomator)简要介绍
    UltraEdit正则表达式介绍及实例
    addr2line -f -e *.so 0x9d69
    Android执行shell命令
    Drawable、Bitmap、byte[]之间的转换
    Ubuntu 12.04 64bit 配置完android 5.0编译环境后出现“could not write bytes: Broken pipe.”而无法进入输入帐号密码的登陆界面
    CameraTest
  • 原文地址:https://www.cnblogs.com/zhenjianyu/p/13221959.html
Copyright © 2020-2023  润新知