js二叉树基本应用

二叉树作为一种子节点不超过两个的树形结构,在查询检索方面的性能还是不错的。比如对于敏感词信息的检索上,无论是链表还是map,其性能都无法跟二叉树相比较。

1 定义

1.1 几个约定:

1.1.1 左节点的值<父节点的值<右节点的值

//定义节点对象
var Node=function(data,left,right){
	this.data=data;
	this.left=left;
	this.right=right;
	
}

//二叉树对象
var BST=function(){
	this.root=null;
	this.fnInsert=fnInsert;//插入
	this.fnInorder=fnInorder;//遍历
	this.fnGetMin=fnGetMin;//获取最小值
	this.fnGetMax=fnGetMax;//获取最大值
	this.fnFind=fnFind;//检索查询
	this.fnRemove=fnRemove;//删除
}

2 几个方法:

//插入节点
//插入节点
/**
 * 1 从根节点开始执行插入操作
 * 2 判断当前值与 当前节点的大小-依次是左节点-右节点
 * 3 如果比当前节点小,且左节点不存在,放置在左节点
 * 4 如果比当前节点大,且右节点不存在,放置在右节点
 * @param {Object} data
 */
var fnInsert=function(data){
	var node=new Node(data,null,null);
	if(this.root==null){
		this.root=node;
	}else{
		var current=this.root;
		var parent;
		while(true){
			parent=current;
			if(data>parent.data){
				if(parent.right==null){
					parent.right=node;
					break;
				}
				current=parent.right;
			}else{
				if(parent.left==null){
					parent.left=node;
					break;
				}
				current=parent.left;
			}
		}
	}
	
}

var fnInorder =function(node){
	if(node!=null){
		console.log(node.data);
		fnInorder(node.left);
		fnInorder(node.right);
	}
}

//查找最小值-最左侧节点值
var fnGetMin=function(){
	var current=this.root;
	while(current.left!=null){
		current=current.left;
	}
	return current.data;
}

//查找最大值-最右侧节点值
var fnGetMax=function(){
	var current=this.root;
	while(current.right!=null){
		current=current.right;
	}
	
	return current.data;
}

//查询检索--当前节点-左节点-右节点循环遍历
var fnFind=function(data){
	var current=this.root;
	while(current!=null){
		if(current.data==data){
			return current;
		}else if(current.data<data) {
			current=current.right;
		}else {
			current=current.left;
		}
	}
	return null;
}

//删除节点
var fnRemove=function(data){
	root=fnRemoveNode(this.root,data);
}

//删除节点
/**
 * 1 当前节点没有子节点-直接删除
 * 2 当前节点只有一个子节点-当前节点的父节点指向其子节点
 * 3 当前节点有两个子节点
 * 3.1 查询当前节点右节点的最小值-或者当前节点左节点的最大值--至于为什么-看图体会
 * 3.2 将上一步查找到的节点放置于当前节点
 * 3.3 移除3.1查找到的节点
 * @param {Object} data
 */
var fnGetSmallest=function(node){
	var current=node;
	while(current.left!=null){
		current=current.left;
	}
	return current;
}

//
var fnRemoveNode=function(node,data){
	if(node==null){
		return null;
	}
	if(node.data==data){
		if(node.right==null&&node.left==null){
			return null;
		}
		if(node.left==null){
			return node.right;
		}
		if(node.right==null){
			return node.left;
		}
		var temNode=fnGetSmallest(node.right);
		node.data=temNode.data;
		node.right=fnRemoveNode(node.right,temNode.data);
		return node;
	}else if(data<node.data){
		node.left=fnRemoveNode(node.left,data);
		return node;
	}else{
		node.right=fnRemoveNode(node.right,data);
		return node;
	}
	
}

测试:

var bst=new BST();
bst.fnInsert(23);
bst.fnInsert(46);
bst.fnInsert(15);
bst.fnInsert(37);
bst.fnInsert(3);
bst.fnInsert(99);
bst.fnInsert(21);
bst.fnInsert(22);
bst.fnInsert(17);
bst.fnInorder(bst.root);
console.log(bst);
var min=bst.fnGetMin();//获取最小值
var max=bst.fnGetMax();//获取最大值
console.log('min,max',min,max);
var cur3=bst.fnFind(3);
var cur13=bst.fnFind(13);
console.log(cur3);
console.log(cur13);
bst.fnRemove(15);//移除节点
bst.fnInorder(bst.root);
console.log(bst);

删除前节点:

3 一个应用--统计文本单词的数量;

3.1 修改Node,添加count属性

//定义节点对象
var Node=function(data,left,right){
	this.data=data;
	this.count=1;
	this.left=left;
	this.right=right;
	
}

3.2 添加统计方法;

var fnUpdate=function(data){
	var node=this.fnFind(data);
	node.count++;
	return node;
}

3.3 修改Bst

//二叉树对象
var BST=function(){
	this.root=null;
	this.fnInsert=fnInsert;//插入
	this.fnInorder=fnInorder;//遍历
	this.fnGetMin=fnGetMin;//获取最小值
	this.fnGetMax=fnGetMax;//获取最大值
	this.fnFind=fnFind;//检索查询
	this.fnRemove=fnRemove;//删除
	this.fnUpdate=fnUpdate;//更新
}

3.4测试

var str='aa,bb,dd,cc,dd,ee,aa,bb,cc,dd,dd,aa,dd,dd,aa,ee,dd,ee';
var bst=new BST();
var strArr=str.split(',');
for(var i=0;i<strArr.length;i++){
	var node=bst.fnFind(strArr[i]);
	if(node==null){
		bst.fnInsert(strArr[i]);
	}else{
		bst.fnUpdate(strArr[i]);
	}
}
bst.fnInorder(bst.root);

结果:

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值