UNPKG

datastructure-ts

Version:

Collection of data structures(LinkedList, DoubleLinkedList, Stack, Queue, Dictionary and etc...) for TypeScript.

478 lines (411 loc) 18.9 kB
import { BinaryTree, BinaryTreeNode } from '../../src'; import { expect } from 'chai'; describe('BinaryTree', () => { describe('getRoot()', () => { it('should return the root node', () => { const tree = new BinaryTree<number>(); expect(tree.getRoot().getValue()).equal(null); }); }); describe('findNode()', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return null if the tree is empty', () => { const emptyTree = new BinaryTree<number>(); expect(emptyTree.findNode(10)).equal(null); }); it('should return the root node if its value matches', () => { expect(tree.findNode(10)).equal(tree.getRoot()); }); it('should return the correct node if it exists in the tree', () => { expect(tree.findNode(3)).equal(tree.getRoot().getLeft().getLeft()); expect(tree.findNode(8)).equal(tree.getRoot().getLeft().getRight()); expect(tree.findNode(15)).equal(tree.getRoot().getRight()); }); it('should return null if the node does not exist in the tree', () => { expect(tree.findNode(20)).equal(null); }); it('should return the first matching node if multiple nodes have the same value', () => { const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(10)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(10)); const treeWithDuplicates = new BinaryTree<number>(); treeWithDuplicates['_root'] = rootNode; expect(treeWithDuplicates.findNode(10)).equal(rootNode); }); it('should be able to find a node with a string value', () => { const rootNode = new BinaryTreeNode<string>('hello'); rootNode.setLeft(new BinaryTreeNode<string>('world')); const treeWithStrings = new BinaryTree<string>(); treeWithStrings['_root'] = rootNode; expect(treeWithStrings.findNode('hello')).equal(rootNode); expect(treeWithStrings.findNode('world')).equal(rootNode.getLeft()); }); }); describe('insert()', () => { let tree: BinaryTree<number>; beforeEach(() => { tree = new BinaryTree<number>(); }); it('should insert the root node when the tree is empty', () => { tree.insert(10); expect(tree.getRoot().getValue()).equal(10); }); it('should insert a new node to the left when the value is less than the root node value', () => { tree.insert(10); tree.insert(5); expect(tree.getRoot().getLeft().getValue()).equal(5); }); it('should insert a new node to the right when the value is greater than the root node value', () => { tree.insert(10); tree.insert(15); expect(tree.getRoot().getRight().getValue()).equal(15); }); it('should not insert a node with the same value as an existing node', () => { tree.insert(10); tree.insert(10); expect(tree.getRoot().getLeft()).equal(null); expect(tree.getRoot().getRight()).equal(null); }); }); describe('delete', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should not do anything if the tree is empty', () => { const emptyTree = new BinaryTree<number>(); emptyTree.delete(10); expect(emptyTree.getRoot().getValue()).equal(null); }); it('should remove the root node if it matches the value', () => { tree.delete(10); expect(tree.getRoot().getValue()).equal(15); expect(tree.getRoot().getLeft().getValue()).equal(5); expect(tree.getRoot().getRight()).equal(null); }); it('should remove a leaf node if it matches the value', () => { tree.delete(8); expect(tree.getRoot().getValue()).equal(10); expect(tree.getRoot().getLeft().getValue()).equal(5); expect(tree.getRoot().getLeft().getLeft().getValue()).equal(3); expect(tree.getRoot().getLeft().getRight()).equal(null); expect(tree.getRoot().getRight().getValue()).equal(15); }); it('should remove a node with one child if it matches the value', () => { tree.delete(5); expect(tree.getRoot().getValue()).equal(10); expect(tree.getRoot().getLeft().getValue()).equal(8); expect(tree.getRoot().getLeft().getLeft().getValue()).equal(3); expect(tree.getRoot().getLeft().getRight()).equal(null); expect(tree.getRoot().getRight().getValue()).equal(15); }); it('should remove a node with two children if it matches the value', () => { tree.delete(5); expect(tree.getRoot().getValue()).equal(10); expect(tree.getRoot().getLeft().getValue()).equal(8); expect(tree.getRoot().getLeft().getLeft().getValue()).equal(3); expect(tree.getRoot().getLeft().getRight()).equal(null); expect(tree.getRoot().getRight().getValue()).equal(15); }); it('should not do anything if the value does not exist in the tree', () => { tree.delete(20); expect(tree.getRoot().getValue()).equal(10); expect(tree.getRoot().getLeft().getValue()).equal(5); expect(tree.getRoot().getLeft().getLeft().getValue()).equal(3); expect(tree.getRoot().getLeft().getRight().getValue()).equal(8); expect(tree.getRoot().getRight().getValue()).equal(15); }); }); describe('inOrderTraversal', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return an empty array for an empty tree', () => { const emptyTree = new BinaryTree<number>(); expect(emptyTree.inOrderTraversal()).to.deep.equal([]); }); it('should return the values in ascending order for a non-empty tree', () => { expect(tree.inOrderTraversal()).to.deep.equal([3, 5, 8, 10, 15]); }); }); describe('preOrderTraversal', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return an empty array for an empty tree', () => { const emptyTree = new BinaryTree<number>(); expect(emptyTree.preOrderTraversal()).to.deep.equal([]); }); it('should return the values in pre-order for a non-empty tree', () => { expect(tree.preOrderTraversal()).to.deep.equal([10, 5, 3, 8, 15]); }); }); describe('postOrderTraversal', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return an empty array for an empty tree', () => { const emptyTree = new BinaryTree<number>(); expect(emptyTree.postOrderTraversal()).to.deep.equal([]); }); it('should return the values in post-order for a non-empty tree', () => { expect(tree.postOrderTraversal()).to.deep.equal([3, 8, 5, 15, 10]); }); }); describe('levelOrderTraversal', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return an empty array for an empty tree', () => { const emptyTree = new BinaryTree<number>(); expect(emptyTree.levelOrderTraversal()).to.deep.equal([]); }); it('should return the values in level-order for a non-empty tree', () => { expect(tree.levelOrderTraversal()).to.deep.equal([10, 5, 15, 3, 8]); }); }); describe('getHeight', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return 0 for an empty tree', () => { const emptyTree = new BinaryTree<number>(); expect(emptyTree.getHeight()).to.equal(0); }); it('should return 1 for a tree with only the root node and set value', () => { const singleNodeTree = new BinaryTree<number>(); singleNodeTree['_root'] = new BinaryTreeNode<number>(10); expect(singleNodeTree.getHeight()).to.equal(1); }); it('should return the height of the tree', () => { expect(tree.getHeight()).to.equal(3); }); }); describe('getDepth', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return 0 for an empty tree', () => { const emptyTree = new BinaryTree<number>(); expect(emptyTree.getDepth(new BinaryTreeNode<number>(10))).to.equal(0); }); it('should return 1 for the root node of a tree', () => { expect(tree.getDepth(tree.getRoot())).to.equal(1); }); it('should return the depth of a node in the tree', () => { expect(tree.getDepth(tree.getRoot().getLeft())).to.equal(2); expect(tree.getDepth(tree.getRoot().getRight())).to.equal(2); expect(tree.getDepth(tree.getRoot().getLeft())).to.equal(2); expect(tree.getDepth(tree.getRoot().getLeft().getRight())).to.equal(0); }); it('should return 0 for a node not in the tree', () => { expect(tree.getDepth(new BinaryTreeNode<number>(20))).to.equal(0); }); }); describe('BinaryTree', () => { describe('getMinNode()', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return the node with the minimum value when called with the root node', () => { const minNode = tree.getMinNode(); expect(minNode.getValue()).equal(3); }); it('should return the node with the minimum value when called with a left child node', () => { const leftNode = tree.getRoot().getLeft(); const minNode = tree.getMinNode(leftNode); expect(minNode.getValue()).equal(3); }); it('should return the node with the minimum value when called with a right child node', () => { const rightNode = tree.getRoot().getRight(); const minNode = tree.getMinNode(rightNode); expect(minNode.getValue()).equal(15); }); }); }); describe('getMaxNode()', () => { let tree: BinaryTree<number>; beforeEach(() => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); tree = new BinaryTree<number>(); tree['_root'] = rootNode; }); it('should return the max node in the entire tree if no argument is provided', () => { expect(tree.getMaxNode().getValue()).equal(15); }); it('should return the max node in the subtree rooted at the provided node', () => { const root = tree.getRoot(); const left = root.getLeft(); const right = root.getRight(); expect(tree.getMaxNode(root).getValue()).equal(15); expect(tree.getMaxNode(left).getValue()).equal(8); expect(tree.getMaxNode(right).getValue()).equal(15); }); }); describe('BinaryTree', () => { describe('toArray()', () => { it('should return an empty array for an empty tree', () => { const tree = new BinaryTree<number>(); expect(tree.toArray()).to.deep.equal([]); }); it('should return the values of the nodes in in-order traversal', () => { // Create a sample binary tree // 10 // / \ // 5 15 // / \ // 3 8 const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); const tree = new BinaryTree<number>(); tree['_root'] = rootNode; expect(tree.toArray()).to.deep.equal([3, 5, 8, 10, 15]); }); }); }); describe('BinaryTree', () => { describe('toString()', () => { it('should return a string representation of the tree in order traversal', () => { const rootNode = new BinaryTreeNode<number>(10); rootNode.setLeft(new BinaryTreeNode<number>(5)); rootNode.setRight(new BinaryTreeNode<number>(15)); rootNode.getLeft().setLeft(new BinaryTreeNode<number>(3)); rootNode.getLeft().setRight(new BinaryTreeNode<number>(8)); const tree = new BinaryTree<number>(); tree['_root'] = rootNode; expect(tree.toString()).to.equal('3, 5, 8, 10, 15'); }); }); }); });