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)