Add binary search tree.

This commit is contained in:
Oleksii Trekhleb 2018-04-02 17:50:56 +03:00
parent 00e40a0eca
commit d6be33842c
8 changed files with 184 additions and 1 deletions

View File

@ -6,6 +6,7 @@
"jest/globals": true
},
"rules": {
"no-bitwise": "off"
"no-bitwise": "off",
"no-lonely-if": "off"
}
}

View File

@ -10,6 +10,7 @@
4. [Hash Table](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/hash-table)
5. [Heap](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/heap)
5. [Trie](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/trie)
6. [Binary Search Tree](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/binary-search-tree)
## [Algorithms](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms)

View File

@ -0,0 +1,37 @@
export default class BinaryTreeNode {
constructor(value = null, left = null, right = null) {
this.left = left;
this.right = right;
this.value = value;
}
addLeft(node) {
this.left = node;
return this;
}
addRight(node) {
this.right = node;
return this;
}
hasLeft() {
return !!this.left;
}
hasRight() {
return !!this.right;
}
traverseInOrder() {
return Array.prototype.concat(
this.left ? this.left.traverseInOrder() : [null],
[this.value],
this.right ? this.right.traverseInOrder() : [null],
);
}
toString() {
return this.traverseInOrder().filter(value => !!value).toString();
}
}

View File

@ -0,0 +1,38 @@
import BinaryTreeNode from '../BinaryTreeNode';
describe('BinaryTreeNode', () => {
it('should create node', () => {
const node = new BinaryTreeNode();
expect(node).toBeDefined();
expect(node.value).toBeNull();
expect(node.left).toBeNull();
expect(node.right).toBeNull();
expect(node.hasLeft()).toBeFalsy();
expect(node.hasRight()).toBeFalsy();
const leftNode = new BinaryTreeNode(1);
const rightNode = new BinaryTreeNode(3);
const rootNode = new BinaryTreeNode(2);
rootNode
.addLeft(leftNode)
.addRight(rightNode);
expect(rootNode.value).toBe(2);
expect(rootNode.left.value).toBe(1);
expect(rootNode.right.value).toBe(3);
});
it('should traverse node', () => {
const leftNode = new BinaryTreeNode(1);
const rightNode = new BinaryTreeNode(3);
const rootNode = new BinaryTreeNode(2, leftNode, rightNode);
expect(rootNode.traverseInOrder()).toEqual([null, 1, null, 2, null, 3, null]);
expect(rootNode.toString()).toBe('1,2,3');
});
});

View File

@ -0,0 +1,19 @@
import BinarySearchTreeNode from './BinarySearchTreeNode';
export default class BinarySearchTree {
constructor() {
this.root = new BinarySearchTreeNode();
}
insert(value) {
this.root.insert(value);
}
contains(value) {
return this.root.contains(value);
}
toString() {
this.root.toString();
}
}

View File

@ -0,0 +1,38 @@
import BinaryTreeNode from '../BinaryTreeNode';
export default class BinarySearchTreeNode extends BinaryTreeNode {
insert(value) {
if (value < this.value) {
// Insert to the left.
if (this.left) {
this.left.insert(value);
} else {
this.left = new BinarySearchTreeNode(value);
}
} else {
// Insert to the right.
if (this.right) {
this.right.insert(value);
} else {
this.right = new BinarySearchTreeNode(value);
}
}
return this;
}
contains(value) {
// Check the root.
if (this.value === value) {
return true;
}
if (value < this.value && this.left) {
return this.left.contains(value);
} else if (this.right) {
return this.right.contains(value);
}
return false;
}
}

View File

@ -0,0 +1,5 @@
describe('BinarySearchTree', () => {
it('should create binary search tree', () => {
});
});

View File

@ -0,0 +1,44 @@
import BinarySearchTreeNode from '../BinarySearchTreeNode';
describe('BinarySearchTreeNode', () => {
it('should create binary search tree', () => {
const bstNode = new BinarySearchTreeNode(2);
expect(bstNode.value).toBe(2);
expect(bstNode.left).toBeNull();
expect(bstNode.right).toBeNull();
});
it('should insert nodes in correct order', () => {
const bstNode = new BinarySearchTreeNode(2);
bstNode.insert(1);
expect(bstNode.toString()).toBe('1,2');
expect(bstNode.contains(1)).toBeTruthy();
expect(bstNode.contains(3)).toBeFalsy();
bstNode.insert(3);
expect(bstNode.toString()).toBe('1,2,3');
expect(bstNode.contains(3)).toBeTruthy();
expect(bstNode.contains(4)).toBeFalsy();
bstNode.insert(7);
expect(bstNode.toString()).toBe('1,2,3,7');
expect(bstNode.contains(7)).toBeTruthy();
expect(bstNode.contains(8)).toBeFalsy();
bstNode.insert(4);
expect(bstNode.toString()).toBe('1,2,3,4,7');
expect(bstNode.contains(4)).toBeTruthy();
expect(bstNode.contains(8)).toBeFalsy();
bstNode.insert(6);
expect(bstNode.toString()).toBe('1,2,3,4,6,7');
expect(bstNode.contains(6)).toBeTruthy();
expect(bstNode.contains(8)).toBeFalsy();
});
});