UNPKG

data-structures-again

Version:

A Javascript library of simple data structures

588 lines (498 loc) 12.9 kB
const BST = require('./BST') const Node = require('../BinaryTreeNode') it('should instantiate', () => { const bst = new BST() expect(bst).toBeDefined() }) it('should insert first node with data - 10', () => { const bst = new BST() bst.insert(10) expect(bst.root.data).toBe(10) }) it('should insert second node with data - 5 in left', () => { const bst = new BST() bst.insert(10) bst.insert(5) expect(bst.root.left.data).toBe(5) }) it('should insert third node with data - 20 in right', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) expect(bst.root.right.data).toBe(20) }) it('should search existing node', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) expect(bst.search(20)).toBe(bst.root.right) }) it('should search existing node in left sub tree', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) expect(bst.search(5)).toBe(bst.root.left) }) it('should return null if searching nonexisting node', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) expect(bst.search(30)).toBe(null) }) it('should delete element with not children', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.delete(20) expect(bst.root.data).toBe(10) expect(bst.root.left.data).toBe(5) expect(bst.root.right).toBe(null) }) it('should delete element with 1 child(right)', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(30) bst.delete(20) bst.delete(100) /* 10 5 20 30 */ expect(bst.root.data).toBe(10) expect(bst.root.left.data).toBe(5) expect(bst.root.right.data).toBe(30) }) it('should delete element with 1 child(right)', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(30) bst.delete(5) /* 10 5 20 30 */ expect(bst.root.data).toBe(10) expect(bst.root.right.data).toBe(20) expect(bst.root.right.right.data).toBe(30) }) it('should delete element with 1 child(left)', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(15) bst.delete(20) /* 10 5 20 15 */ expect(bst.root.data).toBe(10) expect(bst.root.left.data).toBe(5) expect(bst.root.right.data).toBe(15) }) it('should delete element with both children', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(15) bst.insert(30) bst.delete(20) /* 10 5 20 15 30 */ expect(bst.root.data).toBe(10) expect(bst.root.left.data).toBe(5) expect(bst.root.right.data).toBe(30) }) it('should delete element with both children with more nodes', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) bst.delete(20) /* <- Before -> 10 5 20 15 30 50 <- After -> 10 5 30 15 50 */ expect(bst.root.data).toBe(10) expect(bst.root.left.data).toBe(5) expect(bst.root.right.data).toBe(30) expect(bst.root.right.right.data).toBe(50) }) it('should check isBST example 1', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) /* 10 5 20 */ expect(bst.isBST()).toBe(true) }) it('should check isBST example 2', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) bst.delete(20) /* <- Before -> 10 5 20 15 30 50 */ expect(bst.isBST()).toBe(true) }) it('should check isBST example 3', () => { const bst = new BST() bst.root = new Node(4) bst.root.left = new Node(2) bst.root.right = new Node(5) bst.root.left.left = new Node(1) const node = new Node() node.data = 3 bst.root.left.right = node /* 4 2 5 1 3 */ expect(bst.isBST()).toBe(true) }) it('should check isBST example 4', () => { const bst = new BST() bst.root = new Node(3) bst.root.left = new Node(2) bst.root.right = new Node(5) bst.root.right.left = new Node(1) bst.root.right.right = new Node(4) /* 3 2 5 1 4 */ expect(bst.isBST()).toBe(false) }) it('should check isBST example 5', () => { const bst = new BST() bst.root = new Node(6) bst.root.left = new Node(2) bst.root.right = new Node(8) bst.root.left.left = new Node(1) bst.root.left.right = new Node(9) /* 6 2 8 1 9 */ expect(bst.isBST()).toBe(false) }) test('min should return null in empty tree', () => { const bst = new BST() expect(bst.min()).toBe(null) }) it('should get min node in BST', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 15 30 50 */ expect(bst.min().data).toBe(5) }) it('should get max node in BST', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 15 30 50 */ expect(bst.max().data).toBe(50) }) test('max should return null in empty tree', () => { const bst = new BST() expect(bst.max()).toBe(null) }) it('should get correct LCA of existing two numbers', () => { const bst = new BST() expect(bst.lca()).toEqual(null) bst.insert(10) bst.insert(5) bst.insert(2) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 2 15 30 50 */ expect(bst.lca()).toBe(null) expect(bst.lca(15)).toBe(null) expect(bst.lca(15, undefined)).toBe(null) expect(bst.lca(5, 2).data).toBe(5) expect(bst.lca(15, 50).data).toBe(20) expect(bst.lca(15, 50).data).toBe(20) expect(bst.lca(50, 15).data).toBe(20) expect(bst.lca(5, 50).data).toBe(10) expect(bst.lca(30, 50).data).toBe(30) expect(bst.lca(15, 30).data).toBe(20) }) it('should get shortest path between two nodes', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) bst.insert(2) /* <- Before -> 10 5 20 2 15 30 50 */ expect(bst.shortestPath(15, 50)).toEqual([15, 20, 30, 50]) expect(bst.shortestPath(15, 30)).toEqual([15, 20, 30]) expect(bst.shortestPath(50, 15)).toEqual([15, 20, 30, 50]) expect(bst.shortestPath(5, 50)).toEqual([5, 10, 20, 30, 50]) expect(bst.shortestPath(10, 10)).toEqual([10]) expect(bst.shortestPath(10, 20)).toEqual([10, 20]) expect(bst.shortestPath(20, 50)).toEqual([20, 30, 50]) expect(bst.shortestPath(2, 50)).toEqual([2, 5, 10, 20, 30, 50]) expect(bst.shortestPath(2, 15)).toEqual([2, 5, 10, 20, 15]) expect(bst.shortestPath(5, 15)).toEqual([5, 10, 20, 15]) }) it('should insert alphabets correctly', () => { const bst = new BST((a, b) => { return a.charCodeAt() - b.charCodeAt() }) bst.insert('B').insert('A').insert('C').insert('D') /* B A C D */ expect(bst.root.data).toBe('B') expect(bst.root.left.data).toBe('A') expect(bst.root.right.data).toBe('C') expect(bst.root.right.right.data).toBe('D') }) it('should run in-order traverse correctly', () => { const bst = new BST((a, b) => { return a.charCodeAt() - b.charCodeAt() }) bst.insert('B').insert('A').insert('C').insert('D') /* B A C D */ expect(bst.traverse('inorder')).toBe('A B C D') }) it('should run pre-order traverse correctly', () => { const bst = new BST((a, b) => { return a.charCodeAt() - b.charCodeAt() }) bst.insert('B').insert('A').insert('C').insert('D') /* B A C D */ expect(bst.traverse('preorder')).toBe('B A C D') }) it('should run post-order traverse correctly', () => { const bst = new BST((a, b) => { return a.charCodeAt() - b.charCodeAt() }) bst.insert('B').insert('A').insert('C').insert('D') /* B A C D */ expect(bst.traverse('postorder')).toBe('A D C B') }) it('should return in-order traverse on toString call', () => { const bst = new BST((a, b) => { return a.charCodeAt() - b.charCodeAt() }) bst.insert('B').insert('A').insert('C').insert('D') /* B A C D */ expect(bst.toString()).toBe('A,B,C,D') }) it('should give correct size of nodes', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(2) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 2 15 30 50 */ // console.log(JSON.stringify(bst.root, null, 2)) expect(bst.size(bst.root)).toBe(7) expect(bst.size(bst.root.left)).toBe(2) expect(bst.size(bst.root.right)).toBe(4) }) it('should give correct rank of nodes', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(2) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 2 15 30 50 */ // console.log(JSON.stringify(bst.root, null, 2)) expect(bst.rank(21)).toBe(5) expect(bst.rank(3)).toBe(1) expect(bst.rank(51)).toBe(7) }) it('should give correct floor value of nodes', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(2) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 2 15 30 50 */ expect(bst.floor(21)).toBe(20) expect(bst.floor(6)).toBe(5) }) it('should give correct ceil value of nodes', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(2) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 2 15 30 50 */ expect(bst.ceil(21)).toBe(30) expect(bst.ceil(6)).toBe(10) }) it('should give correct range count', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(2) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 2 15 30 50 */ expect(bst.rangeCount(1, 3)).toBe(1) expect(bst.rangeCount(4, 35)).toBe(5) expect(bst.rangeCount(2, 15)).toBe(4) }) it('should give correct range count', () => { const bst = new BST() bst.insert(10) bst.insert(5) bst.insert(2) bst.insert(20) bst.insert(15) bst.insert(30) bst.insert(50) /* <- Before -> 10 5 20 2 15 30 50 */ expect(bst.rangeSearch(4, 35)).toEqual([5, 10, 15, 20, 30]) expect(bst.rangeSearch(2, 15)).toEqual([2, 5, 10, 15]) })