mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-07-05 08:26:14 +08:00
Add binary search tree.
This commit is contained in:
@ -6,6 +6,7 @@
|
|||||||
"jest/globals": true
|
"jest/globals": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-bitwise": "off"
|
"no-bitwise": "off",
|
||||||
|
"no-lonely-if": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
4. [Hash Table](https://github.com/trekhleb/javascript-algorithms/tree/master/src/data-structures/hash-table)
|
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. [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)
|
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)
|
## [Algorithms](https://github.com/trekhleb/javascript-algorithms/tree/master/src/algorithms)
|
||||||
|
|
||||||
|
37
src/data-structures/tree/BinaryTreeNode.js
Normal file
37
src/data-structures/tree/BinaryTreeNode.js
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
38
src/data-structures/tree/__test__/BinaryTreeNode.test.js
Normal file
38
src/data-structures/tree/__test__/BinaryTreeNode.test.js
Normal 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');
|
||||||
|
});
|
||||||
|
});
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
describe('BinarySearchTree', () => {
|
||||||
|
it('should create binary search tree', () => {
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
Reference in New Issue
Block a user