二叉树算法原理
1. 二叉树特点
左子树 < 父节点 < 右子树
2. 中序遍历
先遍历左子树,再访问父节点,再遍历右子树, 可以实现从小到大的排序
3. 前序遍历
先访问父节点,再遍历左子树,再遍历右子树 可以实现复制一颗二叉树,比重新构建二叉树快十倍左右
4. 后序遍历
先遍历左子树,再遍历右子树,再访问父节点 可以应用到文件系统的中,先访问它的左右子树,最后来访问这个节点本身
5. 二叉树查找
- 最小值:递归查找左子树
- 最大数:递归查找右子树
- 具体数:先判断大于父节点还是小于父节点,如果小于父节点,进入左子树;如果大于父节点,进入右子树;递归查找
6. 二叉树子节点的删除,最终目标是保持二叉树的排序性
7.具体实现
function BinaryTree(){
this.root = null;
var Node = function(key){
this.key = key;
this.left = null;
this.right = 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){
let node = new Node(key);
if(this.root === null){
this.root = node;
}else {
insertNode(this.root,node);
}
}
var inOrderTravelNode = function(node,callback){
if(node!==null){
inOrderTravelNode(node.left,callback);
callback(node.key);
inOrderTravelNode(node.right,callback);
}
}
// 中序遍历
this.inOrderTravel = function(callback){
inOrderTravelNode(this.root,callback)
}
var searchNode = function(node,key){
if(node === null){
console.log("查找失败");
}
else if(node.key > key){
searchNode(node.left,key);
}else if(node.key < key){
searchNode(node.right,key);
}else {
console.log("找到了");
}
}
//具体值查找
this.search = function(key){
if(this.root !== null){
searchNode(this.root,key);
}
}
//查找右子树最小节点(也就是当前父节点的右子树的左子树)
var findMinNode = function(node){
if(node){
while(node && node.left !== null) {
node = node.left;
}
return node;
}
return null;
}
var that = this;
var removeNode = function(node,key){
if(node === null){
console.log("查找失败");
}
else if(node.key > key){
node.left = removeNode(node.left,key);
return node;
}else if(node.key < key){
node.right = removeNode(node.right,key);
return node;
}else {
//没有子节点
if(node.left === null && node.right === null){
node = null;
console.log("该节点已删除");
return node;
}
//一个子节点
if(node.left === null){
node = node.right;
return node;
} else if(ndoe.right === null) {
node = node.left;
return node;
}
// 两个子节点,从右子树里找到最小子节点,然后替换父节点的值,并删除这个最小子节点
var minNode = findMinNode(node.right);
node.key = minNode.key;
node.right = removeNode(node.right,minNode);
return node;
}
}
//删除子节点
this.remove = function(key){
this.root = removeNode(this.root,key);
}
}
let node = [10,3,5,6,7,2,12,4,18,9,1]
let binaryTree = new BinaryTree();
//创建二叉树
node.forEach(key=>{
binaryTree.insert(key);
})
var callback = function(key){
console.log("中序遍历:"+key);
}
// 中序遍历
binaryTree.inOrderTravel(callback);
// 二叉树查找子节点
binaryTree.search(7);
//二叉树删除子节点
binaryTree.remove(1);