树是计算机科学中经常用到的一种数据结构。树是一种非线性的数据结构,以分成的方式存储数据,树被用来存储具有层级关系的数据,比如文件系统的文件,树还被用来存储有序列表。我们要研究的是二叉树,在二叉树上查找元素非常快,为二叉树添加元素或者删除元素,也是非常快的。我们现在最主要的是要来学习二叉树,二叉树是一种特殊的树,它的特征是 子节点个数不超过2个。如下图就是二叉树的基本结构示意图如下:
左子节点的值 < 父节点的值 <= 右节点的值
二叉树是由节点组成的,所以我们需要定义一个对象node,可以保存数据,也可以保存其他节点的链接(left 和 right),show()方法用来显示保存在节点中的数据。
下面对于顺序二叉树的的创建,遍历,添加,查找最大值最小值和指定值的寻找及删除功能,提供源码,仅供参考:
function BinaryTree() {
var Node = function(key) {
this.key = key;
this.left = null;
this.right = null;
}
var root = null;
var insertNode = function(node, newNode) {
if (node.key > newNode.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 inorderTraverseNode = function(node, callback) {
if (node != null) {
inorderTraverseNode(node.left, callback);
callback(node.key);
inorderTraverseNode(node.right, callback);
}
}
//中序遍历
this.inOrderTraverse = function(callback) {
inorderTraverseNode(root, callback);
}
//最小节点
var minNode = function(node) {
if (node) {
while (node.left !== null) {
return minNode(node.left);
}
return node.key;
}
return null;
}
this.min = function() {
return minNode(root);
}
//最大节点
var maxNode = function(node) {
if (node) {
while (node.right !== null) {
return maxNode(node.right);
}
return node.key;
}
return null;
}
this.max = function() {
return maxNode(root);
}
//查找指定值有返回true,没有则返回false
var searchNode = function(key, node) {
if (node == null) {
return false;
}
if (node.key > key) {
return searchNode(key, node.left);
} else if (node.key < key) {
return searchNode(key, key.right);
} else {
return true;
}
}
this.search = function(key) {
return searchNode(key, root);
}
//删除指定的节点
var removeNode = function(key, node) {
if (node == null)
return false;
if (key < node.key) {
var node1 = removeNode(key, node.left);
node.left = node1;
return node;
} else if (key > node.key) {
node.right = removeNode(key, node.right);
} else {
if (node.left === null && node.right === null) { //叶子节点的删除
node = null;
return node;
} else if (node.right === null) { //只有左子树的节点删除
node = node.left;
return node;
} else if (node.left === null) { //只有右子树的节点删除
node = node.right;
return node;
} else { //中间节点,既有左子树也有右子树,删除原理:左子树上的所有节点肯定比被删除的节点小,则不需要动,右子树有可能是一群树链,要找到这群树链中的最小值所在的节点,将此最小值赋值给被删除的节点,并删除该最小值所在的节点,这样可以保证被删除的节点后的值肯定比右边的所有节点小,比所有节点大。
node.key = minNode(node.right);
removeNode(node.key, node.right);
return node;
}
}
}
this.remove = function(key) {
return removeNode(key, root);
}
}
var nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13];
var binaryTree = new BinaryTree();
nodes.forEach(function(value, key) {
binaryTree.insert(value);
});
var callback = function(key) {
console.log(key);
}
binaryTree.inOrderTraverse(callback);
console.log(binaryTree.min());
console.log(binaryTree.max());
console.log(binaryTree.search(4));
console.log(binaryTree.search(100));
binaryTree.remove(3); //删除中间节点
binaryTree.inOrderTraverse(callback);