先举个例子,假设有个长度为10的数组,我们需要判断其中是否包含包含某个数字。通常我们会这样写
function search(arr, num){
for(let i = 0; i < arr.length; i++){
if(arr[i] === num){
return true
}
}
return false;
}
// 或者
Array.includes(num);
在数据量少时这样没有任何问题。但是假如这个数组的长度1000000,那就意味着查找的次数最多是1000000次。这样就很不合理。所以这种场景我们可以使用二叉搜索树来查找。
什么是二叉搜索树
比如上图这个结构,以55
为根节点,比55
大的放到左边,比55
小的放到右边。以此类推将所有的数字都放到这棵树上。
我们可以发现任何一个节点他左边的数字都会比他大,而右边的数字都会比他小。这样的一棵树就是二叉搜索树。
用JS构建二叉搜索树
我们需要将原来的数组结构变为二叉搜索树结构。
// 二叉搜索树
function Node(value) {
this.value = value;
this.left = null;
this.right = null;
}
function addNode(root, num) {
if (root === null) {
return;
}
if (root.value === num) {
return;
}
if (num > root.value) {
// 大的放左边
if(root.left === null) {
root.left = new Node(num)
} else {
addNode(root.left, num)
}
} else {
// 小的放右边
if(root.right === null) {
root.right = new Node(num)
} else {
addNode(root.right, num)
}
}
}
function buildBinaryTree(arr) {
if(arr === null|| arr.length === 0){
return null
}
const root = new Node(arr[0]);
for (let idx = 0; idx < arr.length; idx++) {
addNode(root, arr[idx])
}
return root;
}
查找
funtion binaryTreeSearch(root, num) {
if (root === null) {
return false;
}
if (root.value === num) {
return true;
}
if (num > root.value) {
return search(root.left, num)
} else {
return search(root.right, num)
}
}
对比两种查找方式速度
const arr = new Array(100000).fill(1).map(() => parserInt(Math.random() * 1000000));
const binaryTree = buildBinaryTree(arr);
binaryTreeSearch(binaryTree, 33);
search(arr, 33);
通过比较二叉搜索的速度是普通搜索的几十倍。如果数据量超级大效果会更明显。
二叉树搜索虽然很快但是也有缺点,就是内存开销大,我们要为每个数字创建一个节点。所以在数据量少时不建议使用。