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)

 

 

 

 

 
posted @ 2020-08-28 17:25  天高任鸟飞吧  阅读(251)  评论(0编辑  收藏  举报