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);

結果:

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章