二叉搜索树

50 阅读1分钟

先举个例子,假设有个长度为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次。这样就很不合理。所以这种场景我们可以使用二叉搜索树来查找。

什么是二叉搜索树

image.png

比如上图这个结构,以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);


image.png 通过比较二叉搜索的速度是普通搜索的几十倍。如果数据量超级大效果会更明显。

二叉树搜索虽然很快但是也有缺点,就是内存开销大,我们要为每个数字创建一个节点。所以在数据量少时不建议使用。