JavaScript实现排序二叉树
- 二叉树介绍
二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。是数据结构中的一类。在一般情况下,查询效率比链表结构要高。排序二叉树有一个最上层的根节点,小于根节点的归到根节点的左子树中,大于根节点的归到根节点的右子树中,以此类推。没有子节点的节点称之为叶子节点。
- 排序二叉树的创建
首先创建一个二叉树的Node结构,然后定义一个根节点。
var node = function (key){
this.key = key;
this.left = null;
this.right = null;
}
var root = null;
创建一个构建二叉树逻辑 ,insert
方法传入一个node值,实例化一个节点,判断是否有根节点,没有就将值赋给根节点,有的话运行insertNode
方法,传入根节点和实例化的节点。
insertNode
方法比对父节点的值和当前节点的值,层层往下,知道没有节点后新建节点。
//构建二叉树
var insertNode = function(node,newNode){
if(node.key > newNode.key){
if(node.left === null){
node.left = newNode;
}else{
insertNode(node.left,newNode);
}
}else{
if(node.right === null){
node.right = newNode;
}else{
insertNode(node.right,newNode);
}
}
}
this.insert = function(key){
var newNode = new node(key);
if(root === null){
root = newNode;
}else{
insertNode(root,newNode)
}
};
- 前序遍历
//前序遍历
var frontTraverseNode = function(node,callback){
if(node !== null){
callback(node.key);
frontTraverseNode(node.left,callback);
frontTraverseNode(node.right,callback);
}
}
this.frontTraverse = function(callback){
frontTraverseNode(root,callback)
}
前序遍历可以将二叉树重新复制,效率比重新创建一个二叉树更高。callback
参数传入一个方法,为每个节点的处理函数 :
var callback = function (key){ console.log(key); }
- 中序遍历
//中序遍历二叉树
var inOlderTraverseNode = function(node , callback){
if(node !== null){
inOlderTraverseNode(node.left,callback);
callback(node.key)
inOlderTraverseNode(node.right,callback)
}
};
this.inOlderTraverse = function(callback){
inOlderTraverseNode(root,callback)
}
中序遍历的顺序是升序排序的,节点值从小到大。
- 后序遍历
//后序遍历
var laterTraverseNode = function(node,callback){
if(node !== null){
laterTraverseNode(node.left,callback);
laterTraverseNode(node.right,callback);
callback(node.key);
}
}
this.laterTraverse = function(callback){
laterTraverseNode(root,callback)
}
后序遍历从节点的最下层开始排序,然后一层一层往上。多适用于文件系统。
- 查找最小值
//查找最小值
var minNode = function(node){
if(node){
while(node && node.left !== null){
node = node.left;
}
return node.key;
};
return null;
}
this.findMin = function(){
return minNode(root);
}
想要查找最小值只需要一直获取最左边的节点。
- 查找最大值
//查找最大值
var maxNode = function(node){
if(node){
while(node && node.right !== null){
node = node.right;
}
return node.key;
};
return null;
}
this.findMax = function(){
return maxNode(root);
}
获取最大值与最小值类似,获取最右的节点就可以了。
- 查找是否存在节点
//查找是否存在值
var searchNode = function (node,value){
if(node !== null){
if(value === node.key){
return node;
}else if(node.key > value ){
return searchNode(node.left,value);
}else{
return searchNode(node.right,value);
}
}else{
return null;
}
}
this.search = function (value){
return searchNode(root,value)
}
查找是从上向下通过对比查询值和节点值来寻找,找到查询值就返回该节点,未找到就返回null
- 删除节点
//删除节点
var removeNode = function (node,value){
if(node === null){
return null;
};
if(value > node.key){
node.right = removeNode(node.right,value);
return node;
}else if(value < node.key){
node.left = removeNode(node.left,value);
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;
}else{
let min = minNode(node.right);
node.key = min;
node.left = removeNode(node.left,min)
return node;
}
}
}
this.remove = function (value){
removeNode(root,value)
}
删除节点需要找到删除的节点,如果是叶子节点,就将节点的值设置成null
。如果不是叶子节点,那就继续判断是只有左子节点还是只有右子节点还是两个子节点都有。只有左子节点和右子节点很简单只需要将删除的node
变更为左子节点或者右子节点
if(node.left === null){
node = node.right;
return node;
}else if(node.right === null){
node = node.left;
return node;
}
如果既有左子节点又有右子节点,根据二叉树的排序性质,那就需要将找到右子节点最小的节点值,然后将删除节点值变更为右子节点最小的节点值,最后删除右子节点最小的节点,避免存在两个相同值的节点。
- 删除前
- 删除节点3后
以上是我对二叉树学习的一些心得 大家如果想更加详细的学习二叉树排序可以去慕课网 Javascript实现二叉树算法观看视频学习。