[trie] The Trie's getWords method now offers an optional parameter to retrieve all words in case of an empty string input.

This commit is contained in:
Revone 2023-10-28 15:50:42 +08:00
parent f90afe0b57
commit f8e0607b25
15 changed files with 56 additions and 47 deletions

View file

@ -115,7 +115,8 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
* Represents a binary tree data structure.
* @template N - The type of the binary tree's nodes.
*/
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>> implements IBinaryTree<V, N> {
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>>
implements IBinaryTree<V, N> {
/**
* Creates a new instance of BinaryTree.
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
@ -974,7 +975,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
if (current.left) queue.push(current.left);
if (current.right) queue.push(current.right);
}
}
}
return ans;

View file

@ -24,7 +24,9 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
}
}
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>> extends BinaryTree<V, N> implements IBinaryTree<V, N> {
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
extends BinaryTree<V, N>
implements IBinaryTree<V, N> {
/**
* The constructor function initializes a binary search tree object with an optional comparator
* function.

View file

@ -19,7 +19,9 @@ export class RBTreeNode<V = any, N extends RBTreeNode<V, N> = RBTreeNodeNested<V
}
}
export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>> extends BST<V, N> implements IBinaryTree<V, N> {
export class RBTree<V, N extends RBTreeNode<V, N> = RBTreeNode<V, RBTreeNodeNested<V>>>
extends BST<V, N>
implements IBinaryTree<V, N> {
constructor(options?: RBTreeOptions) {
super(options);
}

View file

@ -241,9 +241,10 @@ export class Trie {
* @param {string} prefix - The `prefix` parameter is a string that represents the prefix that we want to search for in the
* trie. It is an optional parameter, so if no prefix is provided, it will default to an empty string.
* @param {number} max - The max count of words will be found
* @param isAllWhenEmptyPrefix - If true, when the prefix provided as '', returns all the words in the trie.
* @returns {string[]} an array of strings.
*/
getWords(prefix = '', max = Number.MAX_SAFE_INTEGER): string[] {
getWords(prefix = '', max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false): string[] {
prefix = this._caseProcess(prefix);
const words: string[] = [];
let found = 0;
@ -270,7 +271,8 @@ export class Trie {
if (nodeC) startNode = nodeC;
}
}
if (startNode !== this.root) dfs(startNode, prefix);
if (isAllWhenEmptyPrefix || startNode !== this.root) dfs(startNode, prefix);
return words;
}

View file

@ -183,7 +183,7 @@ describe('Individual package BST operations test', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<{ key: number; keyA: number }>();
const objBST = new BST<{key: number; keyA: number}>();
expect(objBST).toBeInstanceOf(BST);
objBST.add(11, {key: 11, keyA: 11});
objBST.add(3, {key: 3, keyA: 3});

View file

@ -110,7 +110,7 @@ describe('AVL Tree Test', () => {
});
describe('AVLTree APIs test', () => {
const avl = new AVLTree<{ id: number; text: string }>();
const avl = new AVLTree<{id: number; text: string}>();
beforeEach(() => {
avl.clear();
});

View file

@ -1,5 +1,5 @@
import {AVLTree, AVLTreeNode, BinaryTree, BinaryTreeNode, IterationType} from '../../../../src';
import {isDebugTest} from "../../../config";
import {isDebugTest} from '../../../config';
const isDebug = isDebugTest;
// const isDebug = true;
@ -200,7 +200,7 @@ describe('BinaryTree Morris Traversal', () => {
});
describe('BinaryTree APIs test', () => {
const avl = new AVLTree<{ id: number; text: string }>();
const avl = new AVLTree<{id: number; text: string}>();
beforeEach(() => {
avl.clear();
});
@ -226,11 +226,14 @@ describe('BinaryTree traversals', () => {
expect(tree.dfs(node => node.key, 'pre')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
expect(tree.dfs(node => node.key, 'in')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]);
expect(tree.dfs(node => node.key, 'post')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
expect(tree.bfs(node => node.key, tree.root, IterationType.ITERATIVE)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
]);
expect(tree.bfs(node => node.key, tree.root, IterationType.ITERATIVE)).toEqual([
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
]);
const levels = tree.listLevels(node => node.key);
expect(levels).toEqual([[35], [20, 40], [15, 29, 50], [16, 28, 30, 45, 55]]);
isDebug && console.log(levels);
})
});

View file

@ -189,7 +189,7 @@ describe('BST operations test', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<{ key: number; keyA: number }>();
const objBST = new BST<{key: number; keyA: number}>();
expect(objBST).toBeInstanceOf(BST);
objBST.add(11, {key: 11, keyA: 11});
objBST.add(3, {key: 3, keyA: 3});
@ -260,7 +260,7 @@ describe('BST operations test', () => {
objBST.perfectlyBalance();
expect(objBST.isPerfectlyBalanced()).toBe(true);
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
expect(bfsNodesAfterBalanced[0].key).toBe(8);
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
@ -385,7 +385,7 @@ describe('BST operations test', () => {
expect(bfsIDs[1]).toBe(12);
expect(bfsIDs[2]).toBe(16);
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
objBST.bfs(node => bfsNodes.push(node));
expect(bfsNodes[0].key).toBe(2);
expect(bfsNodes[1].key).toBe(12);
@ -435,7 +435,7 @@ describe('BST Performance test', function () {
bst.addMany(nodes);
isDebug && console.log('---add', performance.now() - start);
const startL = performance.now();
const arr: number[][] = bst.listLevels((node) => node.key);
const arr: number[][] = bst.listLevels(node => node.key);
isDebug && console.log('---listLevels', arr);
isDebug && console.log('---listLevels', performance.now() - startL);
});

View file

@ -6,30 +6,30 @@ describe('Overall BinaryTree Test', () => {
bst.add(11);
bst.add(3);
bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], undefined, false);
bst.size === 16; // true
expect(bst.size).toBe(16); // true
bst.has(6); // true
expect(bst.has(6)).toBe(true); // true
bst.getHeight(6) === 2; // true
bst.getHeight() === 5; // true
bst.getDepth(6) === 3; // true
expect(bst.getHeight(6)).toBe(2); // true
expect(bst.getHeight()).toBe(5); // true
expect(bst.getDepth(6)).toBe(3); // true
bst.size === 16; // true
expect(bst.size).toBe(16); // true
bst.has(6); // true
expect(bst.has(6)).toBe(true); // true
bst.getHeight(6) === 2; // true
bst.getHeight() === 5; // true
bst.getDepth(6) === 3; // true
expect(bst.getHeight(6)).toBe(2); // true
expect(bst.getHeight()).toBe(5); // true
expect(bst.getDepth(6)).toBe(3); // true
const leftMost = bst.getLeftMost();
leftMost?.key === 1; // true
leftMost?.key === 1; // true
expect(leftMost?.key).toBe(1);
bst.delete(6);
bst.get(6); // null
bst.get(6); // null
expect(bst.get(6)).toBeNull();
bst.isAVLBalanced(); // true or false
bst.isAVLBalanced(); // true or false
expect(bst.isAVLBalanced()).toBe(true);
const bfsIDs: number[] = [];
bst.bfs(node => bfsIDs.push(node.key));
bfsIDs[0] === 11; // true
bfsIDs[0] === 11; // true
expect(bfsIDs[0]).toBe(11);
const objBST = new BST<{ key: number; keyA: number }>();
const objBST = new BST<{key: number; keyA: number}>();
objBST.add(11, {key: 11, keyA: 11});
objBST.add(3, {key: 3, keyA: 3});
@ -57,10 +57,10 @@ describe('Overall BinaryTree Test', () => {
const avlTree = new AVLTree();
avlTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
avlTree.isAVLBalanced(); // true
expect(avlTree.isAVLBalanced()).toBe(true); // true
avlTree.isAVLBalanced(); // true
expect(avlTree.isAVLBalanced()).toBe(true); // true
avlTree.delete(10);
avlTree.isAVLBalanced(); // true
expect(avlTree.isAVLBalanced()).toBe(true); // true
avlTree.isAVLBalanced(); // true
expect(avlTree.isAVLBalanced()).toBe(true); // true
});
});

View file

@ -206,7 +206,7 @@ describe('TreeMultiset operations test', () => {
});
it('should perform various operations on a Binary Search Tree with object values', () => {
const objTreeMultiset = new TreeMultiset<{ key: number; keyA: number }>();
const objTreeMultiset = new TreeMultiset<{key: number; keyA: number}>();
expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
objTreeMultiset.add(11, {key: 11, keyA: 11});
objTreeMultiset.add(3, {key: 3, keyA: 3});
@ -481,7 +481,7 @@ describe('TreeMultiset Performance test', function () {
}
isDebug && console.log('---add', performance.now() - start);
const startL = performance.now();
treeMS.lesserOrGreaterTraverse((node) => (node.count += 1), CP.lt, inputSize / 2);
treeMS.lesserOrGreaterTraverse(node => (node.count += 1), CP.lt, inputSize / 2);
isDebug && console.log('---lesserOrGreaterTraverse', performance.now() - startL);
});
});

View file

@ -22,7 +22,7 @@ describe('Heap Operation Test', () => {
});
it('should object heap work well', function () {
const minHeap = new MinHeap<{ a: string; key: number }>((a, b) => a.key - b.key);
const minHeap = new MinHeap<{a: string; key: number}>((a, b) => a.key - b.key);
minHeap.add({key: 1, a: 'a1'});
minHeap.add({key: 6, a: 'a6'});
minHeap.add({key: 2, a: 'a2'});
@ -37,7 +37,7 @@ describe('Heap Operation Test', () => {
i++;
}
const maxHeap = new MaxHeap<{ key: number; a: string }>((a, b) => b.key - a.key);
const maxHeap = new MaxHeap<{key: number; a: string}>((a, b) => b.key - a.key);
maxHeap.add({key: 1, a: 'a1'});
maxHeap.add({key: 6, a: 'a6'});
maxHeap.add({key: 5, a: 'a5'});

View file

@ -3,7 +3,7 @@ import {bigO, magnitude} from '../../../utils';
describe('DoublyLinkedList Operation Test', () => {
let list: DoublyLinkedList<number>;
let objectList: DoublyLinkedList<{ keyA: number }>;
let objectList: DoublyLinkedList<{keyA: number}>;
beforeEach(() => {
list = new DoublyLinkedList();

View file

@ -3,10 +3,10 @@ import {bigO, magnitude} from '../../../utils';
describe('SinglyLinkedList Operation Test', () => {
let list: SinglyLinkedList<number>;
let objectList: SinglyLinkedList<{ keyA: number }>;
let objectList: SinglyLinkedList<{keyA: number}>;
beforeEach(() => {
list = new SinglyLinkedList<number>();
objectList = new SinglyLinkedList<{ keyA: number }>();
objectList = new SinglyLinkedList<{keyA: number}>();
});
describe('push', () => {

View file

@ -17,7 +17,7 @@ describe('MaxPriorityQueue Operation Test', () => {
});
it('should add elements and maintain heap property in a object MaxPriorityQueue', () => {
const priorityQueue = new MaxPriorityQueue<{ keyA: number }>((a, b) => b.keyA - a.keyA);
const priorityQueue = new MaxPriorityQueue<{keyA: number}>((a, b) => b.keyA - a.keyA);
priorityQueue.refill([{keyA: 5}, {keyA: 3}, {keyA: 1}]);
priorityQueue.add({keyA: 7});
@ -64,7 +64,7 @@ describe('MaxPriorityQueue Operation Test', () => {
it('should correctly heapify an object array', () => {
const nodes = [{keyA: 5}, {keyA: 3}, {keyA: 7}, {keyA: 1}];
const maxPQ = MaxPriorityQueue.heapify<{ keyA: number }>(nodes, (a, b) => b.keyA - a.keyA);
const maxPQ = MaxPriorityQueue.heapify<{keyA: number}>(nodes, (a, b) => b.keyA - a.keyA);
expect(maxPQ.poll()?.keyA).toBe(7);
expect(maxPQ.poll()?.keyA).toBe(5);

View file

@ -26,7 +26,7 @@ export const bigO = {
function findPotentialN(input: any): number {
let longestArray: any[] = [];
let mostProperties: { [key: string]: any } = {};
let mostProperties: {[key: string]: any} = {};
function recurse(obj: any) {
if (Array.isArray(obj)) {