zoukankan      html  css  js  c++  java
  • javascript 数据结构与算法 —— 二叉数

    二叉树,首先了解一些关于二叉数的概念(来自百度百科)

    1. 二叉树(Binary tree)是树形结构的一个重要类型

    2. 定义: 二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树

    3. 二叉树可以分为: (1.)空二叉树  ;(2.) 只有一个根结点的二叉树 ; (3. ) 只有左子树 ;(4.)只有右子树,(5.)完全二叉树; (6.)满二叉树

    4.  相关术语

    ①结点:包含一个数据元素及若干指向子树分支的信息 
    ②结点的度:一个结点拥有子树的数目称为结点的度
    ③叶子结点:也称为终端结点,没有子树的结点或者度为零的结点 
    ④分支结点:也称为非终端结点,度不为零的结点称为非终端结点 
    ⑤树的度:树中所有结点的度的最大值 
    ⑥结点的层次:从根结点开始,假设根结点为第1层,根结点的子节点为第2层,依此类推,如果某一个结点位于第L层,则其子节点位于第L+1层 
    ⑦树的深度:也称为树的高度,树中所有结点的层次最大值称为树的深度
     
    相关概念了解后,我们使用ts 来写一个二叉数
     

    一、声明一个节点的数据结构接口

    type INodeTree<T> = {
        value: T;
        left: INodeTree<T>|null;
        right: INodeTree<T>|null;
    }

    二、 实现一个节点类

    //实现节点对象
    class TNode<T>{
        public value:T
        public left:INodeTree<T>|null;
        public right:INodeTree<T>|null;
        constructor(data:T){
            this.value = data
            this.left = null
            this.right = null
        }
    }

    三、实现一个二叉数类

    1. 进行二叉排序

    2. 前序遍历:

    3. 中序遍历

    4. 后续遍历

    5. 层次遍历

    6. 找最大值

    7. 找最小值

      1 class BinaryTree<T>{
      2     private data:T[]
      3     private rootNode:INodeTree<T>
      4     /**
      5      * 
      6      * @param data 
      7      */
      8     constructor(data:T[]){
      9         if(!Array.isArray(data)||data.length<1){
     10             throw("参数必须为数组且数组长度不能少于1")
     11         }
     12         this.data = data
     13         this.rootNode = new TNode(data[0]);////初始化根节点
     14       
     15     }
     16     /**
     17      * 二叉排序
     18      *  1. 先判断当前节点node的值 与入排的值key 比大小,小进左,大近右,相等的话默认进右边
     19      *  2. 然后判断是否存在子节点,如果存在,递归比较,否侧,就进排
     20      */
     21     public sortNode():INodeTree<T>{
     22         let handleSortNode = (node:INodeTree<T>,key:T)=>{
     23             // 对比大小
     24             if(node.value>key){
     25 
     26                 //判断是否存在左子节点
     27                 if(node.left===null){
     28                     if(key){
     29                         node.left = new TNode(key)
     30                     }
     31                     
     32                 }else{
     33                     handleSortNode(node.left,key)
     34                 }
     35 
     36             }else{
     37                  //右边同理
     38                  if(node.right==null){
     39                     if(key){
     40                         node.right = new TNode(key)
     41                     }
     42                     
     43                 }else{
     44                     handleSortNode(node.right,key)
     45                 }
     46             }
     47         }
     48         for(let i =1;i<this.data.length;i++){
     49             handleSortNode(this.rootNode,this.data[i])
     50         }
     51         return this.rootNode
     52     }
     53 
     54     /**
     55      * 中序遍历:从根节点开始遍历,从左向右开始访问,根节点值在中间;简单理解就是: 左子树->父节点->右子树
     56      */
     57     public orderSortNode():Array<T>{
     58         let res:T[] = [];
     59         let orderRraverNode = function(node:INodeTree<T>|null){
     60             if(!node) return 
     61             orderRraverNode(node.left)
     62             res.push(node.value)
     63             orderRraverNode(node.right)
     64 
     65         }
     66         orderRraverNode(this.rootNode)
     67         return res
     68     }
     69     /**
     70      * 前序遍历:从根节点开始遍历,从左向右开始访问,最先输出根节点值;简单理解就是: 父节点->左子树->右子树
     71      */
     72     public beforeSortNode():Array<T> {
     73         let res:T[] = [];
     74         let beforeRraverNode = function(node:INodeTree<T>|null){
     75             if(!node) return 
     76             res.push(node.value)
     77             beforeRraverNode(node.left)
     78             beforeRraverNode(node.right)
     79 
     80         }
     81         beforeRraverNode(this.rootNode)
     82         return res
     83     }
     84 
     85     /**
     86      * 后序遍历:从根节点开始遍历,从左向右开始访问,最后才输出根节点值;简单理解就是: 左子树->右子树->父节点
     87      */
     88     public afterSortNode() {
     89         let res:T[] = [];
     90         let afterRraverNode = function(node:INodeTree<T>|null){
     91             if(!node) return 
     92             afterRraverNode(node.left)
     93             afterRraverNode(node.right)
     94             res.push(node.value)
     95 
     96         }
     97         afterRraverNode(this.rootNode)
     98        
     99         return res
    100     }
    101     
    102     /**
    103      * 层次遍历:按照树的层次自上而下的遍历二叉树;利用队列实现
    104      */
    105     public levelSortNode():T[]{
    106         let queue = [this.rootNode];//直接根节点入队
    107         let res:T[] = [] 
    108         while(queue.length>0){
    109             let node = queue.shift();//出队
    110             if(node){
    111                 res.push(node.value)
    112                 if(node.left){
    113                     queue.push(node.left);//入队
    114                 }
    115                 if(node.right){
    116                     queue.push(node.right);//入队
    117                 }
    118             }
    119         }
    120         return res
    121     }
    122 
    123     /**
    124      * 找最小值,其实就是递归左子节点
    125      */
    126     public minNodeValue():T {
    127         
    128         let res:T = this.rootNode.value;
    129         let minNode = this.rootNode.left
    130         while(minNode&&minNode.left){
    131             minNode = minNode.left;
    132             res = minNode.value
    133         }
    134         return res
    135     }
    136 
    137     /**
    138      * 找最小值,其实就是递归右子节点
    139      */
    140     public maxNodeValue():T {
    141         let res:T = this.rootNode.value;
    142         let maxNode = this.rootNode.right
    143         while(maxNode&&maxNode.right){
    144             maxNode = maxNode.right;
    145             res = maxNode.value
    146         }
    147         return res
    148     }
    149 }

    4. 创建一个工厂函数(可省略)

    function createBinaryTree<T>(data:T[]){
        return new BinaryTree(data)
    }

    5. 调用示例 

    // let arr = [10,5,1,3,8,4,2,12,17,11,14,12,20]
    let arr = ['C', 'B', 'E', 'A',"H",'D']
    let res = createBinaryTree(arr)
    // 二叉排序
    let resSort = res.sortNode()
    console.log(resSort)
    
    // 中序遍历
    let resO = res.orderSortNode()
    console.log("resO",resO)
    
    // 前序遍历
    let resB = res.beforeSortNode()
    console.log("resB",resB)
    
    // 后序遍历
    let resF = res.afterSortNode()
    console.log("resF",resF)
    
    // 层次遍历
    let resL = res.levelSortNode()
    console.log("resL",resL)
    
    // 最小值
    let resMin = res.minNodeValue()
    console.log(resMin)
    
    //最大值
    let resMax= res.maxNodeValue()
    console.log(resMax)
     
  • 相关阅读:
    Oracle 数据库基础学习 (五) 多表查询
    Oracle 数据库基础学习 (四) group by的使用
    Oracle 数据库基础学习 (三) Oracle 四个表结构
    SQL简单语句总结习题
    Oracle 数据库基础学习 (二) 学习小例子:创建一个表,记录商品买卖的情况
    Oracle Database 11g For Windows7 旗舰版的安装
    Oracle to_char()函数的使用细则
    Hadoop集群常用的shell命令
    centos常用命令
    ssh免密码登陆(集群多台机器之间免密码登陆)
  • 原文地址:https://www.cnblogs.com/beyonds/p/13578579.html
Copyright © 2011-2022 走看看