JavaScript实现排序二叉树的基本操作
记得一开始学习数据结构用的是c语言实现,学了这么久前端就想用JavaScript来实现一下,顺便复习下数据结构。
先来了解下什么是排序二叉树,排序二叉树是具有以下特点的二叉树
- 若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值,
- 若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值,
- 左、右子树也分别为二叉排序树
下面我们用代码实现一波
首先是树的结构和根节点
var Node = function(key){//节点结构 this.left = null this.right = null this.key = key }
var root = null //根节点
二叉树的插入,基本过程是比较要插入的数和当前节点的值大小,按照 排序二叉树 的特点,左边的值永远小于右边
var insertNode = function(node,newNode){ if(node.key > newNode.key){//要插入的值小于当前节点,左子树遍历 if(node.left === null){ node.left = newNode return }else{ insertNode(node.left,newNode) } }else if(node.key <= newNode.key){//要插入的值小于当前节点,右子树遍历 if(node.right === null){ node.right = newNode }else{ insertNode(node.right,newNode) } } }
插入成功后我们分别来实现排序二叉树的前序,中序和后序遍历
前序遍历是先访问根节点,而后是左右节点
中序遍历先访问左节点,而后是根节点和右节点
后序遍历则先访问左右节点,最后是根节点
代码如下
var inOrderTraverseNode = function(node,callback){//中序遍历 if(node !== null){ inOrderTraverseNode(node.left) console.log(node.key) inOrderTraverseNode(node.right) } }
var preOrderTraverseNode = function(node,callback){//前序遍历 if(node !== null){ console.log(node.key) preOrderTraverseNode(node.left) preOrderTraverseNode(node.right) } }
var afterOrderTraversNode = function(node,callback){//后序遍历 if(node !== null){ afterOrderTraversNode(node.left) afterOrderTraversNode(node.right) console.log(node.key) } }
var Max = function(node){//最大值 if(node.right !== null){ maxNum = Max(node.right) }else{ return node.key } return maxNum }
var Min = function(node){//最小值 if(node.left !== null){ minNum = Min(node.left) }else{ return node.key } return minNum }
寻找 排序二叉树 中的指定值,也很简单,以根节点为界,比左边小到左边找,比右边小去右边
var Search = function(node,key){//寻找指定值 if(node.key === key){ return true }else{ if(key < node.key && node.left !=null){ return Search(node.left,key) }else if(key > node.key && node.left !=null){ return Search(node.right,key) }else{ return false } } }
最麻烦的是删除节点的操作,这里需要分三种情况,删除节点无子树,删除节点为单子树,删除节点有两个子树,
无子树最简单,直接删
if(node.left === null && node.right === null){ node = null return node }
有单子树的:比如下图(画的有点丑。。。),现在我要删掉3,
代码实现如下
else if(node.left !== null && node.right === null){ node = node.left return node }else if(node.left === null && node.right !== null){ node = node.right return node }
最后是删除有两个子树的节点,为了维持我们排序二叉树的性质,首先我们找到要删除节点的右字树的最小值,根据排序二叉树的特点,找到的最小值必定大于要删除节点的左子树的所有值,因为找到的值为右节点的最小值,所以小于要删除节点的右子树的所有值,我们将找到的最小值代替要删除的值,最后删掉一开始找到的最小值的节点,基本过程就相当于替换了要删除节点的值。
下图,我要删掉3
。
按照上面的思想,找到4代替3,然后删掉一开始找到的4所在的节点
依旧满足排序二叉树的特点
else if(node.left !== null && node.right !== null){ var minNode = finMinNode(node.right) node.key = minNode.key node.right = Remove(node.right,minNode.key) return node }
到这里排序二叉树的基本功能都实现了
完整代码在GitHub(求GitHub小星星)上,我把双向链表也用JavaScript实现了下,需要的也可以看看
原文发布时间为:2018年06月23日
原文作者:笑佛弥勒
本文来源: 掘金 如需转载请联系原作者
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Python程序结构2
2018年6月28日笔记 上午上课前分享 高等数学求解及作图软件:mathmatica 5.循环嵌套 循环嵌套1.png-38.7kB 循环嵌套2.png-50.2kB 循环嵌套3.png-46.8kB 循环嵌套4.png-55.6kB 左上九九乘法表 if __name__ == '__main__': for i in range(1,10): for j in range(1,11-i): print("%d*%d=%2d" %(i,j,i*j),end=' ') print() 上面一段代码的运行结果如下: 左上99乘法表.png-15.1kB 左下九九乘法表 if __name__ == '__main__': for i in range(1,10): for j in range(1,i+1): print("%d*%d=%d" %(i,j,i*j),end=' ') print() 上面一段代码的运行结果如下: 左下99乘法表.png-15.1kB 右上九九乘法表 if __name__ == '__main__': for i in range(1,10): for ...
-
下一篇
为什么要有事件循环机制(Event Loop)
事件循环机制(Event Loop)是全面了解javascript代码执行顺序绕不开的一个重要知识点。虽然许多人知道这个知识点非常重要,但是其实很少有人能够真正理解它。特别是在ES6正式支持Promise之后,对于新标准中事件循环的理解就变得更加重要了。这里我们不具体讲Event Loop(有很多文章说得已经足够好了),我们只是做个牵引——为什么需要Event loop和简单介绍。 在知道事件循环机制之前,我们得确信自己掌握了: 执行上下文(Execution context) 函数调用栈(call stack) 队列数据结构(queue) 希望你抛开已有javascript运行机制方面的相关知识,只要知道以上3点知识就好了。 先来看两个简单的例子,看看是否能够得出正确的执行结果。 //demo01 setTimeout(function() { console.log(1); },0); console.log(2); for(var i = 0; i < 5; i++) { console.log(3); } console.log(4); //demo02 console....
相关文章
文章评论
共有0条评论来说两句吧...




微信收款码
支付宝收款码