二叉搜索树

29 阅读1分钟

二叉搜索树新增节点、前序遍历、中序遍历、后序遍历、查找节点、删除节点、查找最大值的节点和最小值的节点

const Compare = {
  LESS_THAN: -1,
  BIGGER_THAN: 1,
  EQUALS: 0,
};
function defaultCompare(a, b) {
  if (a === b) {
    return Compare.EQUALS;
  }
  return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN;
}

class Node {
  constructor(key) {
    this.key = key;
    this.left = null;
    this.right = null;
  }
}

class BinarySearchTree {
  constructor(compareFn = defaultCompare) {
    this.compareFn = compareFn;
    this.root = null;
  }
  insert(key) {
    if (this.root == null) {
      this.root = new Node(key);
    } else {
      this.insertNode(this.root, key);
    }
  }
  insertNode(node, key) {
    // 比较传入的值和现在节点的值哪个大,小于节点左子节点,大于节点右子节点
    if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
      if (node.left == null) {
        node.left = new Node(key);
      } else {
        this.insertNode(node.left, key);
      }
    } else {
      if (node.right == null) {
        node.right = new Node(key);
      } else {
        this.insertNode(node.right, key);
      }
    }
  }
  // 中序遍历
  inOrderTraverse(node = this.root) {
    if (node != null) {
      this.inOrderTraverse(node.left);
      console.log(node.key);
      this.inOrderTraverse(node.right);
    }
  }
  // 前序遍历
  preOrderTraverse(node = this.root) {
    if (node) {
      console.log(node.key);
      this.preOrderTraverse(node.left);
      this.preOrderTraverse(node.right);
    }
  }
  // 后序遍历
  postOrderTraverse(node = this.root) {
    if (node) {
      this.postOrderTraverse(node.left);
      this.postOrderTraverse(node.right);
      console.log(node.key);
    }
  }
  // 找最小
  minNode(node = this.root) {
    let current = node;
    while (current && current.left) {
      current = current.left;
    }
    return current;
  }
  // 最大值节点
  maxNode(node = this.root) {
    let current = node;
    while (current && current.right) {
      current = current.right;
    }
    return current;
  }
  // 根据值查找
  searchNode(node = this.root, target) {
    if (!node) {
      return false;
    }
    if (this.compareFn(node.key, target) === Compare.LESS_THAN) {
      return this.searchNode(node.left, target);
    } else if (this.compareFn(node.key, target) === Compare.BIGGER_THAN) {
      return this.searchNode(node.right, target);
    } else {
      return true;
    }
  }
  remove(key) {
    this.root = this.removeNode(this.root, key);
  }
  removeNode(node, key) {
    if (node == null) {
      return null;
    }
    if (this.compareFn(key, node.key) === Compare.LESS_THAN) {
      node.left = this.removeNode(node.left, key);
      return node;
    } else if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) {
      node.right = this.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;
      }
      const aux = this.minNode(node.right);
      node.key = aux.key;
      node.right = this.removeNode(node.right, aux.key);
      return node;
    }
  }
}