Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [4.1.0] - 2021-04-21

### Added
- `.lowerBound(k)` to find the node with biggest key less or equal a value k.
- `.upperBound(k)` to find the node with smallest key bigger than a value k.

## [4.0.1] - 2021-04-15
### Fixed
- exported AvlTreeNode path.
Expand Down
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Binary Search Tree & AVL Tree (Self Balancing Tree) implementation in javascript
* [.find(key)](#findkey)
* [.min()](#min)
* [.max()](#max)
* [.lowerBound(k)](#lowerboundk)
* [.upperBound(k)](#upperboundk)
* [.root()](#root)
* [.count()](#count)
* [.traverseInOrder(cb)](#traverseinordercb)
Expand Down Expand Up @@ -202,6 +204,49 @@ const max = bst.max();
console.log(max.getKey()); // 90
console.log(max.getValue()); // v4
```

### .lowerBound(k)
finds the node with the biggest key less or equal a given value k.

<table>
<tr>
<th align="center">params</th>
<th align="center">return</th>
<th align="center">runtime</th>
</tr>
<tr>
<td>k: number | string</td>
<td align="center"><a href="#binarysearchtreenode">BinarySearchTreeNode</a> | <a href="#avltreenode">AvlTreeNode</a></td>
<td align="center">O(log(n))</td>
</tr>
</table>

```js
console.log(bst.lowerBound(60).getKey()); // 50
console.log(bst.lowerBound(10)); // null
```

### .upperBound(k)
finds the node with the smallest key bigger than a given value k.

<table>
<tr>
<th align="center">params</th>
<th align="center">return</th>
<th align="center">runtime</th>
</tr>
<tr>
<td>k: number | string</td>
<td align="center"><a href="#binarysearchtreenode">BinarySearchTreeNode</a> | <a href="#avltreenode">AvlTreeNode</a></td>
<td align="center">O(log(n))</td>
</tr>
</table>

```js
console.log(bst.upperBound(75).getKey()); // 80
console.log(bst.upperBound(110)); // null
```

### .root()
returns the root node of the tree.

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@datastructures-js/binary-search-tree",
"version": "4.0.1",
"version": "4.1.0",
"description": "binary search tree & avl tree (self balancing tree) implementation in javascript",
"main": "index.js",
"scripts": {
Expand Down
48 changes: 48 additions & 0 deletions src/binarySearchTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,54 @@ class BinarySearchTree {
return current;
}

/**
* Returns the node with the biggest key less or equal to k
* @public
* @param {number|string} k
* @return {BinarySearchTreeNode|null}
*/
lowerBound(k, current = this._root) {
if (current === null) {
return null;
}

if (current.getKey() === k) {
return current;
}

if (current.getKey() > k) {
return this.lowerBound(k, current.getLeft());
}

if (current.hasRight() && current.getRight().getKey() <= k) {
return this.lowerBound(k, current.getRight());
}

return current;
}

/**
* Returns the node with the smallest key bigger than k
* @public
* @param {number|string} k
* @return {BinarySearchTreeNode|null}
*/
upperBound(k, current = this._root) {
if (current === null) {
return null;
}

if (current.getKey() <= k) {
return this.upperBound(k, current.getRight());
}

if (current.hasLeft() && current.getLeft().getKey() > k) {
return this.upperBound(k, current.getLeft());
}

return current;
}

/**
* Returns the root node
* @public
Expand Down
20 changes: 20 additions & 0 deletions test/binarySearchTree.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,26 @@ describe('BinarySearchTree tests', () => {
});
});

describe('.lowerBound(k)', () => {
it('gets the node with biggest key less or equal k', () => {
expect(bst.lowerBound(60).getKey()).to.equal(50);
});

it('returns null when k is less than all tree keys', () => {
expect(bst.lowerBound(10)).to.equal(null);
});
});

describe('.upperBound(k)', () => {
it('gets the node with smallest key bigger than k', () => {
expect(bst.upperBound(75).getKey()).to.equal(80);
});

it('returns null when k is bigger than all tree keys', () => {
expect(bst.upperBound(110)).to.equal(null);
});
});

describe('.traverseInOrder(cb)', () => {
it('traverse the tree in-order', () => {
const keys = [];
Expand Down