# 树形结构

#### 二叉树和二叉树搜索

``````function BinarySearchTree() {
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);
}
}
};

var inOrderTraversalNode = function (node, callback) {
//中序遍历
if(node !== null) {
inOrderTraversalNode(node.left, callback);
callback(node.key);
inOrderTraversalNode(node.right, callback);
}
};
var preOrderTraversalNode = function (node, callback) {
//先序遍历
if(node !== null) {
callback(node.key);
preOrderTraversalNode(node.left, callback);
preOrderTraversalNode(node.right, callback);
}
};

var postOrderTraversalNode = function (node, callback) {
//后序遍历
if(node !== null) {
postOrderTraversalNode(node.left, callback);
postOrderTraversalNode(node.right, callback);
callback(node.key);
}
};

var minNode = function (node) {
//查找最最小值
if(node !== null) {
while (node && node.left !== null) {
node = node.left;
}
return node.key;
}
return null;
};

var maxNode = function (node) {
//查找最大值
if(node !== null) {
while (node && node.right !== null) {
node = node.right;
}
return node.key;
}
return null;
};
var getMixNode = function (node) {
//查找键值最小的节点返回
if(node !== null) {
while (node && node.left !== null) {
node = getMixNode(node.left);
}
return node;
}
return null;
};

var searchNode = function (node, key) {
//在树中查找一个键是否存在
if(node === null) {
return false;
}
if (key < node.key) {
return searchNode(node.left, key);
}else if (key > node.key) {
return searchNode(node.right, key);
}else {
return true;
}
};

var removeNode = function (node, key) {
if (node === null) {
//当节点等于null说明不存在直接返回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) {
return null;
}
if(node.left === null) {
node = node.right;
return node;
}
if(node.right === null) {
node = node.left;
return node;
}
var aux = getMixNode(node.right);
node.key = aux.key;
removeNode(node.right, aux.key);
}
};

var root = null;

this.insert = function (key) {
//向树中插入一个新键
var newNode = new Node(key);
if (root === null) {
root = newNode;
}else {
insertNode(root, newNode);
}
};

this.search = function (key) {
//在树中查找一个键，如果存在返回true否则false
return searchNode(root, key);
};

this.inOrderTraversal = function (callback) {
//通过中序遍历方式遍历所有节点
inOrderTraversalNode(root, callback);
};

this.preOrderTraversal = function (callback) {
//通过先序遍历方式遍历所有节点
preOrderTraversalNode(root, callback);
};

this.postOrderTraversal = function (callback) {
//通过后续遍历方式遍历所有节点
postOrderTraversalNode(root, callback);
};
this.min = function () {
//返回树中最小值/键
return minNode(root);
};

this.max = function () {
//返回树中最大值/键
return maxNode(root);
};

this.remove = function (key) {
//从树中移除某个键
return removeNode(root, key);
};

}

var tree = new BinarySearchTree();
tree.insert(55);
tree.insert(88);
tree.insert(17);
tree.insert(65);
tree.insert(4);
tree.insert(5);
tree.insert(6);
tree.insert(5);
tree.insert(8);
tree.insert(78);
tree.insert(87);
tree.insert(27);
tree.insert(17);
tree.insert(28);

function printNode(value) {
console.log(value);
}

tree.inOrderTraversal(printNode); //4 5 5 6 8 17 17  27 28 55 65 78 87 88
tree.preOrderTraversal(printNode);//55 17 4 5 6 5 8 27 17 28 88 65 78 87
tree.postOrderTraversal(printNode);// 5 8 6 5 4 17 28 27 17 87 78 65 88 55
console.log(tree.min()); //4

console.log(tree.search(20)); //false
tree.remove(88); //false
console.log(tree.max()); //87

``````