BST的实现
其中对于二叉树删除节点最为复杂。
需要考虑节点是叶节点,有一个孩子(叶节点),有两个叶节点三种情况。
但是利用搜索二叉树左孩子小于右孩子的特点。
进行删除。
并且BST的实现很好的体现了递归的思想。
可以借此学习。
function printNode(value) {
console.log(value);
}
function BinarySearchTree() {
//插入新键
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)
}
}
}
//中序遍历
var inOrderTraverseNode = function (node, callback) {
if (node !== null){
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
}
//先序
var preOrderTraverseNode = function (node, callback) {
if (node !== null){
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
}
}
//后序
var postOrderTraverseNode = function (node, callback) {
if (node !== null){
postOrderTraverseNode(node.left, callback);
postOrderTraverseNode(node.right, callback);
callback(node.key);
}
}
//最小值
var minNode = function (node) {
if(node){
while (node && node.left !== null) {
node = node.left;
}
return node.key;
}
return null;
}
//最大值
var maxNode = function (node) {
if(node){
while (node && node.right !== null) {
node = node.right;
}
return node.key;
}
return null;
}
//搜索
var searchNode = function (node, key) {
if(node === null){
return false;
}
if(key < node.key){
searchNode(node.left, key);
}else if(key > node.key){
searchNode(node.right, key);
}else{
return true;
}
}
//移除一个结点
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;
return node;
}
//当有两个结点时
console.log('已经查询到这里了')
var aux = findMinNode(node.right);
console.log(aux.key)
node.key = aux.key;
console.log('这是现在的node值'+node.key)
node.right = removeNode(node.right, aux.key);
console.log('这是node.right值'+node.right)
return node;
}
}
var findMinNode = function (node) {
while (node && node.left!==null){
node = node.left;
}
return node;
}
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
}
var root = null;
//向树中插入一个新键
this.insert = function (key) {
var newNode = new Node(key);
if(root === null){
root = newNode;
}else{
insertNode(root, newNode);
}
}
//中序遍历
this.inOrderTraverse = function (callback) {
inOrderTraverseNode(root, callback);
}
//先序遍历
this.preOrderTraverse = function (callback) {
preOrderTraverseNode(root, callback);
}
//后序遍历
this.postOrderTraverse = function (callback) {
postOrderTraverseNode(root, callback);
}
//搜索最小值。二叉搜索树,最小值为左树或者根
this.min = function () {
return minNode(root);
}
//搜索最大值。二叉搜索树,最大值为右树或者根
this.max = function () {
return maxNode(root);
}
//搜索一个特定的值
this.search = function (key) {
return searchNode(root, key);
}
//移除一个结点
this.remove = function (key) {
root = removeNode(root, key);
}
}
var tree = new BinarySearchTree();
tree.insert(7)
tree.insert(15)
tree.insert(5)
tree.insert(3)
tree.insert(9)
tree.insert(8)
tree.insert(10)
tree.insert(13)
tree.insert(12)
tree.insert(14)
tree.insert(20)
tree.insert(18)
tree.insert(25)
tree.inOrderTraverse(printNode)
console.log(tree.max())
console.log(tree.min())
tree.remove(15)
tree.inOrderTraverse(printNode)
AVL树
AVL自平衡树,每个节点左子树高度和右子树高度差值为0,1或者-1
function AVLTree() {
var Node = function (key) {
this.key = key;
this.left = null;
this.right = null;
};
var root = null;
this.getRoot = function () {
return root;
};
//插入新节点
var insertNode = function (node, element) {
if (node === null) {
node = new Node(element);
} else if (element < node.key) {
node.left = insertNode(node.left, element)
if (node.left !== null) {
//确认是否需要平衡
if ((heightNode(node.left) - heightNode(node.right)) > 1) {
//旋转
if (element < node.left.key) {
node = rotationLL(node);
} else {
node = rotationLR(node);
}
}
}
} else if (element > node.key) {
node.right = insertNode(node.right, element)
if (node.right !== null) {
//确认是否需要平衡
if ((heightNode(node.right) - heightNode(node.left)) > 1) {
//旋转
if (element > node.right.key) {
node = rotationRR(node);
} else {
node = rotationRL(node);
}
}
}
}
return node;
}
//计算节点高度
var heightNode = function (node) {
if (node === null) {
return -1;
} else {
return Math.max(heightNode(node.left), heightNode(node.right)) + 1;
}
}
//右-右(RR):向左的单旋转
var rotationRR = function(node) {
var tmp = node.right;
node.right = tmp.left;
tmp.left = node;
return tmp;
};
//左-左(LL):向右的单旋转
var rotationLL = function(node) {
var tmp = node.left;
node.left = tmp.right;
tmp.right = node;
return tmp;
};
//左-右(LR):向右的双旋转
var rotationLR = function (node) {
node.left = rotationRR(node.left);
return rotationLL(node);
}
// 右-左(RL):向左的双旋转
var rotationRL = function (node) {
node.left = rotationLL(node.right);
return rotationRR(node);
}
this.insert = function(element) {
root = insertNode(root, element);
};
var parentNode;
var nodeToBeDeleted;
var removeNode = function(node, element) {
if (node === null) {
return null;
}
parentNode = node;
if (element < node.key) {
node.left = removeNode(node.left, element);
} else {
nodeToBeDeleted = node;
node.right = removeNode(node.right, element);
}
if (node === parentNode) { //remove node
if (nodeToBeDeleted !== null && element === nodeToBeDeleted.key) {
if (nodeToBeDeleted === parentNode) {
node = node.left;
} else {
var tmp = nodeToBeDeleted.key;
nodeToBeDeleted.key = parentNode.key;
parentNode.key = tmp;
node = node.right;
}
}
} else { //do balancing
if (node.left === undefined) node.left = null;
if (node.right === undefined) node.right = null;
if ((heightNode(node.left) - heightNode(node.right)) === 2) {
if (element < node.left.key) {
node = rotationLR(node);
} else {
node = rotationLL(node);
}
}
if ((heightNode(node.right) - heightNode(node.left)) === 2) {
if (element > node.right.key) {
node = rotationRL(node);
} else {
node = rotationRR(node);
}
}
}
return node;
};
this.remove = function(element) {
parentNode = null;
nodeToBeDeleted = null;
root = removeNode(root, element);
};
}
有兴趣可以加入Nodejs交流群,和大佬们一起成长!!!
群号:348108867
图片.png