排序二叉树,就是节点的左孩子远小于节点本身,右孩子永远大于节点本身。从而形成了一个排序二叉树。
如下图
function BinaryTree(){
var Node = function(key){
this.key = key;
this.left = null;
this.right = null;
};
var root = null;
var insertNode = function(node,newNode){
if(newNode.key<node.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 nodes = [8,3,10,1,6,14,4,7,13];
var binaryTree = new BinaryTree();
nodes.forEach(function(key){
binaryTree.insert(key);
});
以上代码就简单构造了一个排序二叉树。
二叉树的遍历:分为前序遍历中序遍历和后序遍历。
以上图二叉树为例
前序遍历:8,3,1,6,4,7,10,14,13. 其原理是先遍历根节点然后再遍历左节点再遍历右节点。
中序遍历:1,3,4,6,7,8,10,13,14.其原理是先遍历左节点再根节点再遍历右节点。
后序遍历:1,4,7,6,3,13,14,10,8其原理是先遍历左右节点在遍历根节点。
接下来是代码实现:(以下代码单独从上边的代码函数BinaryTree()中摘出来的。使用时直接放回BinaryTree()函数中)
var callback = function(key){
console.log(key);
}
callback函数是遍历中使用到的一个回调函数。
var preOrderTraverseNode = function(node,callback){//前序遍历
if(node!==null){
callback(node.key);
inOrderTraverseNode(node.left,callback);
inOrderTraverseNode(node.right,callback);
}
}
this.preOrderTraverse = function(callback){//前序遍历
preOrderTraverseNode(root,callback);
}
以上是前序遍历。
var inOrderTraverseNode = function(node,callback){//中序遍历函数
if(node!==null){
inOrderTraverseNode(node.left,callback);
callback(node.key);
inOrderTraverseNode(node.right,callback);
}
};
this.inOrderTraverse = function(callback){ //中序遍历,原理从根节点先遍历左子树,按左中右的方式斤进行遍历i
inOrderTraverseNode(root,callback);
}
以上是中序遍历。 看完前序遍历和中序遍历我相信大家都应该会自己写后序遍历了。将callback函数放到最后即可。
接下来是二叉树的查找:分为 1.查找排序二叉树中的最小节点。2.查找排序二叉树的最大节点。3.查找排序二叉树的指定节点。
1.查找二叉树中的最小节点:因为排序二叉树的左孩子永远小于父节点,所以,一直找到二叉树根节点的左字数的最左边的叶子节点就是最小节点。
代码如下:
var minNode = function(node){
if(node){
while(node && node.left !==null){ //node存在而且node的左孩子也存在就一直循环
node=node.left;
}
return node.key;
}
}
this.min = function(){
return minNode(root);
}
2.查找最大节点和最小节点大同小异,代码如下:
var maxNode = function(node){
if(node){
while(node && node.right !==null){
node=node.right;
}
return node.key;
}
}
this.max = function(){
return maxNode(root);
}
3.查找指定节点: 先查看根节点是否等于给定节点,如果等于就返回True,如果大于根节点就向右孩子继续查找。如果小于根节点就向左孩子继续查找。利用递归最终匹配指定的节点,如果未匹配到,则返回false
代码如下:
var serachNode = function(node,key){//查找二叉树中是否存在指定节点,存在返回True,否则返回false;
if(node === null){
return false;
}
if(key<node.key){
return serachNode(node.left,key);
} else if(key>node.key){
return serachNode(node.right,key);
} else{
return true;
}
};
this.serach = function(key){
if(serachNode(root,key)){
return true;
}else{
return false;
}
};
二叉树的删除:分为三种情况
1.删除的节点为叶子节点,既没有左字数,也没有右子树。这种情况最简单,直接另Node=null删除节点即可。
2.删除的节点只存在左子树或者右子树,将当前节点置为当前节点的左孩子或右孩子,(node=node.right)二叉树依然保持排序
3.删除的节点又存在左子树也存在右字数例如:删除下图节点3,因为排序二叉树的右孩子总是大于左孩子,所以先将节点3的右字数的最小值选出来,即节点4,然后将节点四替换节点三,然后将节点四删除。这样就实现了节点三的删除,并且保持排序二叉树的排序性质不变。
删除的代码如下:
var removeNode = function(node,key){
if(node===null){
return null;
}
if(key<node.key){ //先通过两个判断语句找到要删除的节点。
node.left = removeNode(node.left,key);
return node;
}else if(key>node.key){
node.right = removeNode(node.right,key);
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;
}
//如果以上条件都不符合,即又存在左孩子,也存在右孩子。
var aux = findMinNode(node.right);
node.key = aux.key;
node.right = removeNode(node.right,aux.key);
return node;
}
};
this.remove = function(key){
root = removeNode(root,key);
}
var findMinNode = function(node){//用于第三种情况找到右子树的最小节点。
if(node){
while(node&&node.left!==null){
node = node.left;
}
return node;
}
return null;
};
以上就是二叉排序树的查找,删除,和排序。
点击打开链接这个链接里面有全部的代码。有需要的可以去看一下。