JS BST as a Bucket
Binary Search Tree as a Bucket\n- The common choice of hash function is %\n- Generally advisable to use a prime number as the base of modulo operator to reduce 
### Binary Search Tree as a Bucket\n- The common choice of hash function is `%`\n- Generally advisable to use a prime number as the base of modulo operator to reduce collisions\n- `N = the range of values, It is 1000001`\n- `K = the number for hash function, I use 769`\n- Time complexity: **O(log(N/K))** `for add, remove and search`\n- Space complexity: **O(N)**\n```JavaScript\n/** Binary Search Tree\n * @param {number} x\n * @return {void}\n */\nfunction Node(x) {\n    this.val = x;\n    this.left = null;\n    this.right = null;\n}\n\n/** \n * @param {number} x\n * @return {Node}\n */\nNode.prototype.add = function(x) {\n    if (!this) {\n        return new Node(x);\n    }\n    if (x === this.val) {\n        return this;\n    } else if (x < this.val) {\n        this.left = this.left ? this.left.add(x) : new Node(x);\n    } else {\n        this.right = this. right ? this.right.add(x) : new Node(x);\n    }\n    return this;\n}\n\n/** \n * @return {number}\n */\nNode.prototype.successor = function() {\n    let node = this.right;\n    while (node.left) {\n        node = node.left;\n    }\n    return node.val;\n}\n\n/** \n * @return {number}\n */\nNode.prototype.predecessor = function() {\n    let node = this.left;\n    while (node.right) {\n        node = node.right;\n    }\n    return node.val;\n}\n\n/** \n * @param {number} x\n * @return {Node}\n */\nNode.prototype.remove = function(x) {\n    if (!this) return null;\n    if (x === this.val) {\n        if (this.right) {\n            this.val = this.successor();\n            this.right = this.val ? this.right.remove(this.val) : null;\n        } else if (this.left) {\n            this.val = this.predecessor();\n            this.left = this.val ? this.left.remove(this.val) : null;\n        } else {\n            return null;\n        }\n    } else if (x > this.val) {\n        this.right = this.right ? this.right.remove(x) : null;\n    } else {\n        this.left = this.left ? this.left.remove(x) : null;\n    } \n    return this;\n}\n\n/** \n * @param {number} x\n * @return {bool}\n */\nNode.prototype.contains = function(x) {\n    if (!this || x === this.val) {\n        return this !== null;\n    }\n    if (x < this.val) {\n        return this.left !== null && this.left.contains(x);\n    }\n    return  this.right !== null && this.right.contains(x);\n}\n\n\n/**\n * @return {void}\n */\nconst MyHashSet = function() {\n    this.hashSet = new Array(769).fill(null);\n};\n\n/** Hash Set\n * @param {number} key\n * @return {void}\n */\nMyHashSet.prototype.add = function(key) {\n    if (!this.hashSet[key%769]) {\n        this.hashSet[key%769] = new Node(key);\n    } else {\n        this.hashSet[key%769].add(key);\n    }\n    \n};\n\n/** \n * @param {number} key\n * @return {void}\n */\nMyHashSet.prototype.remove = function(key) {\n    if (!this.hashSet[key%769]) return;\n    this.hashSet[key%769] = this.hashSet[key%769].remove(key);\n};\n\n/**\n * Returns true if this set contains the specified element \n * @param {number} key\n * @return {boolean}\n */\nMyHashSet.prototype.contains = function(key) {\n    if (!this.hashSet[key%769]) return false;\n    return this.hashSet[key%769].contains(key);\n};\n```
['Binary Search', 'Tree', 'Binary Search Tree', 'JavaScript']