树在优点:搜索速度快,插入删除速度快。
一、插入
insert 添加node,先判断是否有根节点,如果没有则直接插入根节点,如果已经有根节点,则调用isertNode方法。
代码实现:
var Tree = function() {
var root = null;
var Node = function(val) {
this.val = val;
this.left = null;
this.right = null;
}
// insertNode 递归插入
var insertNode = function(node, newNode) {
if(newNode.val < node.val) {
// 插入左边
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)
}
}
}
// insert 插入节点
this.insert = function(val) {
var node = new Node(val);
// 判断root
if(root == null) {
root = node;
} else {
insertNode(root, node);
}
}
//
this.getRoot = function() {
return root;
}
}
var tree1 = new Tree();
tree1.insert(8)
tree1.insert(2)
tree1.insert(3)
tree1.insert(9)
console.log(tree1.getRoot());
二、遍历
代码实现:
// traverseNode
var traverseNode = function(node, callback) {
if(node == null) return;
// callback(node.val); // 8 2 3 9 前序遍历
traverseNode(node.left,callback);
// callback(node.val); // 2 3 8 9 中序遍历
traverseNode(node.right, callback);
callback(node.val); // 3 2 9 8 后序遍历
}
// traverse 遍历树并执行自定义操作
this.traverse = function(callback) {
traverseNode(root,callback);
}
使用:
var tree1 = new Tree();
tree1.insert(8)
tree1.insert(2)
tree1.insert(3)
tree1.insert(9)
console.log(tree1.getRoot());
var print = function(val) {
console.log(val)
}
console.log(tree1.traverse(print));
三、移除
移除: 先查找到想删除的节点;
- 当节点为叶节点时替换为null,并返回;
- 当节点有一个子节点:将node替换为子节点;
-
当节点有两个子节点:查找到右树的最小子节点,替换node,并将右树最小子节点删除
注意:移除成功后都要返回新的树
// finMinNode 查找最小子节点
var finMinNode = function(node) {
if(node == null) return;
while(node && node.left) {
node = node.left;
}
return node;
}
// removeNode 移除递归 返回新的树
var removeNode = function(node,value) {
if(value < node.val) {
// 向左查找:设置新的左子节点
node.left = removeNode(node.left, value);
// console.log(node.left)
return node;
} else if(value > node.val) {
// 向右查找:设置新的右子节点
node.right = removeNode(node.right, value);
return node;
} else {
// value == node.val
// 叶节点:叶节点替换为null,并返回
if(node.left == null && node.right == null) {
// console.log(node)
node = null;
return node;
}
// 一个子节点:将node替换为子节点
if(node.left == null && node.right) {
return node.right;
} else if(node.left && node.right == null) {
return node.left;
}
// 两个子节点:查找到右树的最小子节点,替换node,并将右树最小子节点删除
var aux = finMinNode(node.right); //获取右树的最小子节点
node.val = aux.val;
node.right = removeNode(node.right, aux.val);
return node;
}
}
// remove 移除
this.remove = function(value) {
// removeNode中删除后要创建新的树,所以要赋值给root
root = removeNode(root,value);
}
使用:
var tree1 = new Tree();
tree1.insert(11)
tree1.insert(8)
tree1.insert(4)
tree1.insert(9)
tree1.insert(3)
tree1.insert(5)
tree1.insert(10)
// tree1.remove(3)
// tree1.remove(9)
tree1.remove(8)
console.log(tree1.getRoot());
四、整体代码
var Tree = function() {
var root = null;
var Node = function(val) {
this.val = val;
this.left = null;
this.right = null;
}
// insertNode 递归插入
var insertNode = function(node, newNode) {
if(newNode.val < node.val) {
// 插入左边
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)
}
}
}
// insert 插入节点
this.insert = function(val) {
var node = new Node(val);
// 判断root
if(root == null) {
root = node;
} else {
insertNode(root, node);
}
}
// getRoot 获取根节点
this.getRoot = function() {
return root;
}
// traverseNode
var traverseNode = function(node, callback) {
if(node == null) return;
// callback(node.val); // 8 2 3 9 前序遍历
traverseNode(node.left,callback);
// callback(node.val); // 2 3 8 9
traverseNode(node.right, callback);
callback(node.val); // 3 2 9 8
}
// traverse 遍历树并执行自定义操作
this.traverse = function(callback) {
traverseNode(root,callback);
}
// finMinNode 查找最小子节点
var finMinNode = function(node) {
if(node == null) return;
while(node && node.left) {
node = node.left;
}
return node;
}
// removeNode 移除递归 返回新的树
var removeNode = function(node,value) {
if(value < node.val) {
// 向左查找:设置新的左子节点
node.left = removeNode(node.left, value);
// console.log(node.left)
return node;
} else if(value > node.val) {
// 向右查找:设置新的右子节点
node.right = removeNode(node.right, value);
return node;
} else {
// value == node.val
// 叶节点:叶节点替换为null,并返回
if(node.left == null && node.right == null) {
// console.log(node)
node = null;
return node;
}
// 一个子节点:将node替换为子节点
if(node.left == null && node.right) {
return node.right;
} else if(node.left && node.right == null) {
return node.left;
}
// 两个子节点:查找到右树的最小子节点,替换node,并将右树最小子节点删除
var aux = finMinNode(node.right); //获取右树的最小子节点
node.val = aux.val;
node.right = removeNode(node.right, aux.val);
return node;
}
}
// remove 移除
this.remove = function(value) {
// removeNode中删除后要创建新的树,所以要赋值给root
root = removeNode(root,value);
}
}
var tree1 = new Tree();
tree1.insert(11)
tree1.insert(8)
tree1.insert(4)
tree1.insert(9)
tree1.insert(3)
tree1.insert(5)
tree1.insert(10)
console.log(tree1.getRoot());
// var print = function(val) {
// console.log(val)
// }
// console.log(tree1.traverse(print));
// tree1.remove(3)
// tree1.remove(9)
tree1.remove(8)
console.log(tree1.getRoot());