mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2025-04-25 23:33:31 +00:00
v1.3.3 published
This commit is contained in:
parent
55704871b6
commit
70f439da13
37 changed files with 3642 additions and 3448 deletions
1
.idea/data-structure-typed.iml
generated
1
.idea/data-structure-typed.iml
generated
|
@ -11,6 +11,7 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/backup" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/bst/dist" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/bst/docs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/lib" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
|
143
README.md
143
README.md
|
@ -371,55 +371,103 @@ import {UndirectedGraph} from 'data-structure-typed';
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
## API docs
|
||||
<ul>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/AVLTree.html" rel="nofollow"><span>AVLTree</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/AVLTreeNode.html" rel="nofollow"><span>AVLTreeNode</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/AbstractEdge.html" rel="nofollow"><span>AbstractEdge</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/AbstractGraph.html" rel="nofollow"><span>AbstractGraph</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/AbstractVertex.html" rel="nofollow"><span>AbstractVertex</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/ArrayDeque.html" rel="nofollow"><span>ArrayDeque</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/BST.html" rel="nofollow"><span>BST</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/BSTNode.html" rel="nofollow"><span>BSTNode</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/BinaryIndexedTree.html" rel="nofollow"><span>BinaryIndexedTree</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/BinaryTree.html" rel="nofollow"><span>BinaryTree</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/BinaryTreeNode.html" rel="nofollow"><span>BinaryTreeNode</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Character.html" rel="nofollow"><span>Character</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/CoordinateMap.html" rel="nofollow"><span>CoordinateMap</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/CoordinateSet.html" rel="nofollow"><span>CoordinateSet</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Deque.html" rel="nofollow"><span>Deque</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/DirectedEdge.html" rel="nofollow"><span>DirectedEdge</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/DirectedGraph.html" rel="nofollow"><span>DirectedGraph</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/DirectedVertex.html" rel="nofollow"><span>DirectedVertex</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/DoublyLinkedList.html" rel="nofollow"><span>DoublyLinkedList</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/DoublyLinkedListNode.html" rel="nofollow"><span>DoublyLinkedListNode</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Heap.html" rel="nofollow"><span>Heap</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Matrix2D.html" rel="nofollow"><span>Matrix2D</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/MatrixNTI2D.html" rel="nofollow"><span>MatrixNTI2D</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/MaxHeap.html" rel="nofollow"><span>MaxHeap</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/MaxPriorityQueue.html" rel="nofollow"><span>MaxPriorityQueue</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/MinHeap.html" rel="nofollow"><span>MinHeap</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/MinPriorityQueue.html" rel="nofollow"><span>MinPriorityQueue</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Navigator.html" rel="nofollow"><span>Navigator</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/ObjectDeque.html" rel="nofollow"><span>ObjectDeque</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/PriorityQueue.html" rel="nofollow"><span>PriorityQueue</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Queue.html" rel="nofollow"><span>Queue</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/SegmentTree.html" rel="nofollow"><span>SegmentTree</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/SegmentTreeNode.html" rel="nofollow"><span>SegmentTreeNode</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/SinglyLinkedList.html" rel="nofollow"><span>SinglyLinkedList</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/SinglyLinkedListNode.html" rel="nofollow"><span>SinglyLinkedListNode</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Stack.html" rel="nofollow"><span>Stack</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/TreeMultiSet.html" rel="nofollow"><span>TreeMultiSet</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Trie.html" rel="nofollow"><span>Trie</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/TrieNode.html" rel="nofollow"><span>TrieNode</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/UndirectedEdge.html" rel="nofollow"><span>UndirectedEdge</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/UndirectedGraph.html" rel="nofollow"><span>UndirectedGraph</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/UndirectedVertex.html" rel="nofollow"><span>UndirectedVertex</span></a></li>
|
||||
<li><a href="https://data-structure-typed-docs.vercel.app/classes/Vector2D.html" rel="nofollow"><span>Vector2D</span></a></li>
|
||||
</ul>
|
||||
[//]: # (## API docs)
|
||||
|
||||
[//]: # (<ul>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/AVLTree.html" rel="nofollow"><span>AVLTree</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/AVLTreeNode.html" rel="nofollow"><span>AVLTreeNode</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/AbstractEdge.html" rel="nofollow"><span>AbstractEdge</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/AbstractGraph.html" rel="nofollow"><span>AbstractGraph</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/AbstractVertex.html" rel="nofollow"><span>AbstractVertex</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/ArrayDeque.html" rel="nofollow"><span>ArrayDeque</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/BST.html" rel="nofollow"><span>BST</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/BSTNode.html" rel="nofollow"><span>BSTNode</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/BinaryIndexedTree.html" rel="nofollow"><span>BinaryIndexedTree</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/BinaryTree.html" rel="nofollow"><span>BinaryTree</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/BinaryTreeNode.html" rel="nofollow"><span>BinaryTreeNode</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Character.html" rel="nofollow"><span>Character</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/CoordinateMap.html" rel="nofollow"><span>CoordinateMap</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/CoordinateSet.html" rel="nofollow"><span>CoordinateSet</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Deque.html" rel="nofollow"><span>Deque</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/DirectedEdge.html" rel="nofollow"><span>DirectedEdge</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/DirectedGraph.html" rel="nofollow"><span>DirectedGraph</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/DirectedVertex.html" rel="nofollow"><span>DirectedVertex</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/DoublyLinkedList.html" rel="nofollow"><span>DoublyLinkedList</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/DoublyLinkedListNode.html" rel="nofollow"><span>DoublyLinkedListNode</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Heap.html" rel="nofollow"><span>Heap</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Matrix2D.html" rel="nofollow"><span>Matrix2D</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/MatrixNTI2D.html" rel="nofollow"><span>MatrixNTI2D</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/MaxHeap.html" rel="nofollow"><span>MaxHeap</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/MaxPriorityQueue.html" rel="nofollow"><span>MaxPriorityQueue</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/MinHeap.html" rel="nofollow"><span>MinHeap</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/MinPriorityQueue.html" rel="nofollow"><span>MinPriorityQueue</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Navigator.html" rel="nofollow"><span>Navigator</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/ObjectDeque.html" rel="nofollow"><span>ObjectDeque</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/PriorityQueue.html" rel="nofollow"><span>PriorityQueue</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Queue.html" rel="nofollow"><span>Queue</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/SegmentTree.html" rel="nofollow"><span>SegmentTree</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/SegmentTreeNode.html" rel="nofollow"><span>SegmentTreeNode</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/SinglyLinkedList.html" rel="nofollow"><span>SinglyLinkedList</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/SinglyLinkedListNode.html" rel="nofollow"><span>SinglyLinkedListNode</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Stack.html" rel="nofollow"><span>Stack</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/TreeMultiSet.html" rel="nofollow"><span>TreeMultiSet</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Trie.html" rel="nofollow"><span>Trie</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/TrieNode.html" rel="nofollow"><span>TrieNode</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/UndirectedEdge.html" rel="nofollow"><span>UndirectedEdge</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/UndirectedGraph.html" rel="nofollow"><span>UndirectedGraph</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/UndirectedVertex.html" rel="nofollow"><span>UndirectedVertex</span></a></li>)
|
||||
|
||||
[//]: # (<li><a href="https://data-structure-typed-docs.vercel.app/classes/Vector2D.html" rel="nofollow"><span>Vector2D</span></a></li>)
|
||||
|
||||
[//]: # (</ul>)
|
||||
|
||||
# Why
|
||||
|
||||
## Code design
|
||||
By strictly adhering to object-oriented design (BinaryTree -> BST -> AVLTree -> TreeMultiset), you can seamlessly inherit the existing data structures to implement the customized ones you need. Object-oriented design stands as the optimal approach to data structure design.
|
||||
|
||||
## Complexities
|
||||
|
||||
### performance of Big O
|
||||
|
@ -680,9 +728,6 @@ import {UndirectedGraph} from 'data-structure-typed';
|
|||
</tbody>
|
||||
</table>
|
||||
|
||||
## Code design
|
||||
By strictly adhering to object-oriented design (BinaryTree -> BST -> AVLTree -> TreeMultiset), you can seamlessly inherit the existing data structures to implement the customized ones you need. Object-oriented design stands as the optimal approach to data structure design.
|
||||
|
||||
[//]: # ()
|
||||
|
||||

|
||||
|
|
919
package-lock.json
generated
919
package-lock.json
generated
File diff suppressed because it is too large
Load diff
43
package.json
43
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "data-structure-typed",
|
||||
"version": "1.3.1",
|
||||
"version": "1.3.3",
|
||||
"description": "Data Structures of Javascript & TypeScript. AVLTree, Binary Search Tree, Binary Tree, Tree Multiset, Graph, Heap, Priority Queue, Linked List.",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
|
@ -10,7 +10,7 @@
|
|||
"build:browser": "webpack",
|
||||
"build:docs": "typedoc --out docs ./src",
|
||||
"test": "jest",
|
||||
"update:test-deps": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed --save-dev",
|
||||
"update:test-deps": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed queue-typed --save-dev",
|
||||
"deps:check": "dependency-cruiser src",
|
||||
"build:publish": "npm run test && npm run build && npm run build:docs && npm publish"
|
||||
},
|
||||
|
@ -134,31 +134,32 @@
|
|||
"devDependencies": {
|
||||
"@types/jest": "^29.5.3",
|
||||
"@types/node": "^20.4.9",
|
||||
"avl-tree-typed": "^1.21.3",
|
||||
"binary-tree-typed": "^1.21.3",
|
||||
"bst-typed": "^1.21.3",
|
||||
"avl-tree-typed": "^1.3.3",
|
||||
"binary-tree-typed": "^1.3.3",
|
||||
"bst-typed": "^1.3.3",
|
||||
"dependency-cruiser": "^13.1.2",
|
||||
"deque-typed": "^1.21.3",
|
||||
"directed-graph-typed": "^1.21.3",
|
||||
"doubly-linked-list-typed": "^1.21.3",
|
||||
"graph-typed": "^1.21.3",
|
||||
"heap-typed": "^1.21.3",
|
||||
"deque-typed": "^1.3.3",
|
||||
"directed-graph-typed": "^1.3.3",
|
||||
"doubly-linked-list-typed": "^1.3.3",
|
||||
"graph-typed": "^1.3.3",
|
||||
"heap-typed": "^1.3.3",
|
||||
"jest": "^29.6.2",
|
||||
"linked-list-typed": "^1.21.3",
|
||||
"max-heap-typed": "^1.21.3",
|
||||
"max-priority-queue-typed": "^1.21.3",
|
||||
"min-heap-typed": "^1.21.3",
|
||||
"min-priority-queue-typed": "^1.21.3",
|
||||
"priority-queue-typed": "^1.21.3",
|
||||
"singly-linked-list-typed": "^1.21.3",
|
||||
"stack-typed": "^1.21.3",
|
||||
"tree-multiset-typed": "^1.21.3",
|
||||
"trie-typed": "^1.21.3",
|
||||
"linked-list-typed": "^1.3.3",
|
||||
"max-heap-typed": "^1.3.3",
|
||||
"max-priority-queue-typed": "^1.3.3",
|
||||
"min-heap-typed": "^1.3.3",
|
||||
"min-priority-queue-typed": "^1.3.3",
|
||||
"priority-queue-typed": "^1.3.3",
|
||||
"queue-typed": "^1.3.3",
|
||||
"singly-linked-list-typed": "^1.3.3",
|
||||
"stack-typed": "^1.3.3",
|
||||
"tree-multiset-typed": "^1.3.3",
|
||||
"trie-typed": "^1.3.3",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-loader": "^9.4.4",
|
||||
"typedoc": "^0.24.8",
|
||||
"typescript": "^4.9.5",
|
||||
"undirected-graph-typed": "^1.21.3",
|
||||
"undirected-graph-typed": "^1.3.3",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4"
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ export class DoublyLinkedListNode<T = number> {
|
|||
}
|
||||
}
|
||||
|
||||
export class DoublyLinkedList<T = number> {
|
||||
export class DoublyLinkedList<T = any> {
|
||||
|
||||
/**
|
||||
* The constructor initializes the linked list with an empty head, tail, and length.
|
||||
|
@ -122,8 +122,8 @@ export class DoublyLinkedList<T = number> {
|
|||
* @returns The method is returning the value of the removed node (removedNode.val) if the list is not empty. If the
|
||||
* list is empty, it returns null.
|
||||
*/
|
||||
pop(): T | null {
|
||||
if (!this.tail) return null;
|
||||
pop(): T | undefined {
|
||||
if (!this.tail) return undefined;
|
||||
const removedNode = this.tail;
|
||||
if (this.head === this.tail) {
|
||||
this.head = null;
|
||||
|
@ -141,8 +141,8 @@ export class DoublyLinkedList<T = number> {
|
|||
* @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked
|
||||
* list.
|
||||
*/
|
||||
shift(): T | null {
|
||||
if (!this.head) return null;
|
||||
shift(): T | undefined {
|
||||
if (!this.head) return undefined;
|
||||
const removedNode = this.head;
|
||||
if (this.head === this.tail) {
|
||||
this.head = null;
|
||||
|
@ -180,8 +180,8 @@ export class DoublyLinkedList<T = number> {
|
|||
* @returns The method is returning the value at the specified index in the linked list. If the index is out of bounds
|
||||
* or the linked list is empty, it will return null.
|
||||
*/
|
||||
getAt(index: number): T | null {
|
||||
if (index < 0 || index >= this.length) return null;
|
||||
getAt(index: number): T | undefined {
|
||||
if (index < 0 || index >= this.length) return undefined;
|
||||
let current = this.head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current!.next;
|
||||
|
@ -264,8 +264,8 @@ export class DoublyLinkedList<T = number> {
|
|||
* @returns The method `deleteAt` returns the value of the node that was deleted, or `null` if the index is out of
|
||||
* bounds.
|
||||
*/
|
||||
deleteAt(index: number): T | null {
|
||||
if (index < 0 || index >= this.length) return null;
|
||||
deleteAt(index: number): T | undefined {
|
||||
if (index < 0 || index >= this.length) return undefined;
|
||||
if (index === 0) return this.shift();
|
||||
if (index === this.length - 1) return this.pop();
|
||||
|
||||
|
@ -280,6 +280,7 @@ export class DoublyLinkedList<T = number> {
|
|||
|
||||
delete(valOrNode: T): boolean;
|
||||
delete(valOrNode: DoublyLinkedListNode<T>): boolean;
|
||||
|
||||
/**
|
||||
* The `delete` function removes a node from a doubly linked list based on either the node itself or its value.
|
||||
* @param {T | DoublyLinkedListNode<T>} valOrNode - The `valOrNode` parameter can accept either a value of type `T` or
|
||||
|
@ -495,6 +496,7 @@ export class DoublyLinkedList<T = number> {
|
|||
|
||||
insertAfter(existingValueOrNode: T, newValue: T): boolean;
|
||||
insertAfter(existingValueOrNode: DoublyLinkedListNode<T>, newValue: T): boolean;
|
||||
|
||||
/**
|
||||
* The `insertAfter` function inserts a new node with a given value after an existing node in a doubly linked list.
|
||||
* @param {T | DoublyLinkedListNode<T>} existingValueOrNode - The existing value or node in the doubly linked list
|
||||
|
@ -533,6 +535,7 @@ export class DoublyLinkedList<T = number> {
|
|||
|
||||
insertBefore(existingValueOrNode: T, newValue: T): boolean;
|
||||
insertBefore(existingValueOrNode: DoublyLinkedListNode<T>, newValue: T): boolean;
|
||||
|
||||
/**
|
||||
* The `insertBefore` function inserts a new value before an existing value or node in a doubly linked list.
|
||||
* @param {T | DoublyLinkedListNode<T>} existingValueOrNode - The existing value or node in the doubly linked list
|
||||
|
|
|
@ -173,8 +173,8 @@ export class SinglyLinkedList<T = any> {
|
|||
* @returns The method `getAt(index: number): T | null` returns the value at the specified index in the linked list, or
|
||||
* `null` if the index is out of bounds.
|
||||
*/
|
||||
getAt(index: number): T | null {
|
||||
if (index < 0 || index >= this.length) return null;
|
||||
getAt(index: number): T | undefined {
|
||||
if (index < 0 || index >= this.length) return undefined;
|
||||
let current = this.head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current!.next;
|
||||
|
@ -218,6 +218,7 @@ export class SinglyLinkedList<T = any> {
|
|||
|
||||
delete(valueOrNode: T): boolean;
|
||||
delete(valueOrNode: SinglyLinkedListNode<T>): boolean;
|
||||
|
||||
/**
|
||||
* The delete function removes a node with a specific value from a singly linked list.
|
||||
* @param {T | SinglyLinkedListNode<T>} valueOrNode - The `valueOrNode` parameter can accept either a value of type `T`
|
||||
|
@ -399,6 +400,7 @@ export class SinglyLinkedList<T = any> {
|
|||
|
||||
insertBefore(existingValue: T, newValue: T): boolean
|
||||
insertBefore(existingValue: SinglyLinkedListNode<T>, newValue: T): boolean
|
||||
|
||||
/**
|
||||
* The `insertBefore` function inserts a new value before an existing value in a singly linked list.
|
||||
* @param {T | SinglyLinkedListNode<T>} existingValueOrNode - The existing value or node that you want to insert the
|
||||
|
@ -438,6 +440,7 @@ export class SinglyLinkedList<T = any> {
|
|||
|
||||
insertAfter(existingValueOrNode: T, newValue: T): boolean
|
||||
insertAfter(existingValueOrNode: SinglyLinkedListNode<T>, newValue: T): boolean
|
||||
|
||||
/**
|
||||
* The `insertAfter` function inserts a new node with a given value after an existing node in a singly linked list.
|
||||
* @param {T | SinglyLinkedListNode<T>} existingValueOrNode - The existing value or node in the linked list after which
|
||||
|
@ -487,4 +490,14 @@ export class SinglyLinkedList<T = any> {
|
|||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
* [Symbol.iterator]() {
|
||||
let current = this.head;
|
||||
|
||||
while (current) {
|
||||
yield current.val;
|
||||
current = current.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
import {SinglyLinkedList} from '../linked-list';
|
||||
|
||||
export class Queue<T = any> extends SinglyLinkedList<T> {
|
||||
export class LinkedListQueue<T = any> extends SinglyLinkedList<T> {
|
||||
|
||||
/**
|
||||
* The enqueue function adds a value to the end of an array.
|
||||
|
@ -30,20 +30,9 @@ export class Queue<T = any> extends SinglyLinkedList<T> {
|
|||
peek(): T | undefined {
|
||||
return this.head?.val;
|
||||
}
|
||||
|
||||
* [Symbol.iterator]() {
|
||||
let current = this.head;
|
||||
|
||||
while (current) {
|
||||
yield current.val;
|
||||
current = current.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ArrayQueue<T = number> {
|
||||
protected _nodes: T[];
|
||||
protected _offset: number;
|
||||
export class Queue<T = any> {
|
||||
|
||||
/**
|
||||
* The constructor initializes an instance of a class with an optional array of elements and sets the offset to 0.
|
||||
|
@ -56,12 +45,32 @@ export class ArrayQueue<T = number> {
|
|||
this._offset = 0;
|
||||
}
|
||||
|
||||
private _nodes: T[];
|
||||
|
||||
get nodes(): T[] {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
set nodes(value: T[]) {
|
||||
this._nodes = value;
|
||||
}
|
||||
|
||||
private _offset: number;
|
||||
|
||||
get offset(): number {
|
||||
return this._offset;
|
||||
}
|
||||
|
||||
set offset(value: number) {
|
||||
this._offset = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The size function returns the number of elements in an array.
|
||||
* @returns {number} The size of the array, which is the difference between the length of the array and the offset.
|
||||
*/
|
||||
get size(): number {
|
||||
return this._nodes.length - this._offset;
|
||||
return this.nodes.length - this.offset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,8 +81,8 @@ export class ArrayQueue<T = number> {
|
|||
* @returns The method is returning a new instance of the Queue class, initialized with the elements from the input
|
||||
* array.
|
||||
*/
|
||||
static fromArray<T>(elements: T[]): ArrayQueue<T> {
|
||||
return new ArrayQueue(elements);
|
||||
static fromArray<T>(elements: T[]): Queue<T> {
|
||||
return new Queue(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,8 +90,8 @@ export class ArrayQueue<T = number> {
|
|||
* @param {T} element - The `element` parameter represents the element that you want to add to the queue.
|
||||
* @returns The `add` method is returning a `Queue<T>` object.
|
||||
*/
|
||||
push(element: T): ArrayQueue<T> {
|
||||
this._nodes.push(element);
|
||||
push(element: T): Queue<T> {
|
||||
this.nodes.push(element);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -91,18 +100,18 @@ export class ArrayQueue<T = number> {
|
|||
* necessary to optimize performance.
|
||||
* @returns The function `shift()` returns either the first element in the queue or `null` if the queue is empty.
|
||||
*/
|
||||
shift(): T | null {
|
||||
if (this.size === 0) return null;
|
||||
shift(): T | undefined {
|
||||
if (this.size === 0) return undefined;
|
||||
|
||||
const first = this.peek();
|
||||
this._offset += 1;
|
||||
this.offset += 1;
|
||||
|
||||
if (this._offset * 2 < this._nodes.length) return first;
|
||||
if (this.offset * 2 < this.nodes.length) return first;
|
||||
|
||||
// only remove dequeued elements when reaching half size
|
||||
// to decrease latency of shifting elements.
|
||||
this._nodes = this._nodes.slice(this._offset);
|
||||
this._offset = 0;
|
||||
this.nodes = this.nodes.slice(this.offset);
|
||||
this.offset = 0;
|
||||
return first;
|
||||
}
|
||||
|
||||
|
@ -111,8 +120,8 @@ export class ArrayQueue<T = number> {
|
|||
* @returns The `peek()` method returns the first element of the data structure, represented by the `_nodes` array at
|
||||
* the `_offset` index. If the data structure is empty (size is 0), it returns `null`.
|
||||
*/
|
||||
peek(): T | null {
|
||||
return this.size > 0 ? this._nodes[this._offset] : null;
|
||||
peek(): T | undefined {
|
||||
return this.size > 0 ? this.nodes[this.offset] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -120,8 +129,8 @@ export class ArrayQueue<T = number> {
|
|||
* @returns The method `peekLast()` returns the last element of the `_nodes` array if the array is not empty. If the
|
||||
* array is empty, it returns `null`.
|
||||
*/
|
||||
peekLast(): T | null {
|
||||
return this.size > 0 ? this._nodes[this._nodes.length - 1] : null;
|
||||
peekLast(): T | undefined {
|
||||
return this.size > 0 ? this.nodes[this.nodes.length - 1] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,10 +145,14 @@ export class ArrayQueue<T = number> {
|
|||
* The `dequeue` function removes and returns the first element from a queue, or returns null if the queue is empty.
|
||||
* @returns The method is returning a value of type T or null.
|
||||
*/
|
||||
dequeue(): T | null {
|
||||
dequeue(): T | undefined {
|
||||
return this.shift();
|
||||
}
|
||||
|
||||
getAt(index: number): T | undefined {
|
||||
return this.nodes[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* The function checks if a data structure is empty by comparing its size to zero.
|
||||
* @returns {boolean} A boolean value indicating whether the size of the object is 0 or not.
|
||||
|
@ -153,22 +166,28 @@ export class ArrayQueue<T = number> {
|
|||
* @returns An array of type T is being returned.
|
||||
*/
|
||||
toArray(): T[] {
|
||||
return this._nodes.slice(this._offset);
|
||||
return this.nodes.slice(this.offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* The clear function resets the nodes array and offset to their initial values.
|
||||
*/
|
||||
clear(): void {
|
||||
this._nodes = [];
|
||||
this._offset = 0;
|
||||
this.nodes = [];
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `clone()` function returns a new Queue object with the same elements as the original Queue.
|
||||
* @returns The `clone()` method is returning a new instance of the `Queue` class.
|
||||
*/
|
||||
clone(): ArrayQueue<T> {
|
||||
return new ArrayQueue(this._nodes.slice(this._offset));
|
||||
clone(): Queue<T> {
|
||||
return new Queue(this.nodes.slice(this.offset));
|
||||
}
|
||||
|
||||
* [Symbol.iterator]() {
|
||||
for (const item of this.nodes) {
|
||||
yield item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,114 +1,114 @@
|
|||
import {AVLTree} from 'avl-tree-typed';
|
||||
|
||||
describe('AVL Tree Test', () => {
|
||||
it('should perform various operations on a AVL Tree', () => {
|
||||
it('should perform various operations on a AVL Tree', () => {
|
||||
|
||||
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
const tree = new AVLTree();
|
||||
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
const tree = new AVLTree();
|
||||
|
||||
for (const i of arr) tree.add(i, i);
|
||||
for (const i of arr) tree.add(i, i);
|
||||
|
||||
const node6 = tree.get(6);
|
||||
const node6 = tree.get(6);
|
||||
|
||||
expect(node6 && tree.getHeight(node6)).toBe(3);
|
||||
expect(node6 && tree.getDepth(node6)).toBe(1);
|
||||
expect(node6 && tree.getHeight(node6)).toBe(3);
|
||||
expect(node6 && tree.getDepth(node6)).toBe(1);
|
||||
|
||||
const getNodeById = tree.get(10, 'id');
|
||||
expect(getNodeById?.id).toBe(10);
|
||||
const getNodeById = tree.get(10, 'id');
|
||||
expect(getNodeById?.id).toBe(10);
|
||||
|
||||
|
||||
const getMinNodeByRoot = tree.getLeftMost();
|
||||
expect(getMinNodeByRoot?.id).toBe(1);
|
||||
const getMinNodeByRoot = tree.getLeftMost();
|
||||
expect(getMinNodeByRoot?.id).toBe(1);
|
||||
|
||||
const node15 = tree.get(15);
|
||||
const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
|
||||
expect(getMinNodeBySpecificNode?.id).toBe(12);
|
||||
const node15 = tree.get(15);
|
||||
const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
|
||||
expect(getMinNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && tree.subTreeSum(node15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
const subTreeSum = node15 && tree.subTreeSum(node15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = tree.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
const lesserSum = tree.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
|
||||
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
||||
expect(node15?.val).toBe(15);
|
||||
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
||||
expect(node15?.val).toBe(15);
|
||||
|
||||
const node11 = tree.get(11);
|
||||
const node11 = tree.get(11);
|
||||
|
||||
|
||||
const dfs = tree.DFS('in', 'node');
|
||||
expect(dfs[0].id).toBe(1);
|
||||
expect(dfs[dfs.length - 1].id).toBe(16);
|
||||
const dfs = tree.DFS('in', 'node');
|
||||
expect(dfs[0].id).toBe(1);
|
||||
expect(dfs[dfs.length - 1].id).toBe(16);
|
||||
|
||||
tree.perfectlyBalance();
|
||||
const bfs = tree.BFS('node');
|
||||
expect(tree.isPerfectlyBalanced()).toBe(true);
|
||||
expect(bfs[0].id).toBe(8);
|
||||
expect(bfs[bfs.length - 1].id).toBe(16);
|
||||
tree.perfectlyBalance();
|
||||
const bfs = tree.BFS('node');
|
||||
expect(tree.isPerfectlyBalanced()).toBe(true);
|
||||
expect(bfs[0].id).toBe(8);
|
||||
expect(bfs[bfs.length - 1].id).toBe(16);
|
||||
|
||||
expect(tree.remove(11, true)[0].deleted?.id).toBe(11);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(node15 && tree.getHeight(node15)).toBe(2);
|
||||
expect(tree.remove(11, true)[0].deleted?.id).toBe(11);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(node15 && tree.getHeight(node15)).toBe(2);
|
||||
|
||||
expect(tree.remove(1, true)[0].deleted?.id).toBe(1);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(4);
|
||||
expect(tree.remove(1, true)[0].deleted?.id).toBe(1);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(4);
|
||||
|
||||
expect(tree.remove(4, true)[0].deleted?.id).toBe(4);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(4);
|
||||
expect(tree.remove(4, true)[0].deleted?.id).toBe(4);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(4);
|
||||
|
||||
expect(tree.remove(10, true)[0].deleted?.id).toBe(10);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(10, true)[0].deleted?.id).toBe(10);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(15, true)[0].deleted?.id).toBe(15);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.remove(15, true)[0].deleted?.id).toBe(15);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(5, true)[0].deleted?.id).toBe(5);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(5, true)[0].deleted?.id).toBe(5);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(13, true)[0].deleted?.id).toBe(13);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(13, true)[0].deleted?.id).toBe(13);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(3, true)[0].deleted?.id).toBe(3);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(3, true)[0].deleted?.id).toBe(3);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(8, true)[0].deleted?.id).toBe(8);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(8, true)[0].deleted?.id).toBe(8);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(6, true)[0].deleted?.id).toBe(6);
|
||||
expect(tree.remove(6, true).length).toBe(0);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
expect(tree.remove(6, true)[0].deleted?.id).toBe(6);
|
||||
expect(tree.remove(6, true).length).toBe(0);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
|
||||
expect(tree.remove(7, true)[0].deleted?.id).toBe(7);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
expect(tree.remove(7, true)[0].deleted?.id).toBe(7);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
|
||||
expect(tree.remove(9, true)[0].deleted?.id).toBe(9);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
expect(tree.remove(14, true)[0].deleted?.id).toBe(14);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(1);
|
||||
expect(tree.remove(9, true)[0].deleted?.id).toBe(9);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
expect(tree.remove(14, true)[0].deleted?.id).toBe(14);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(1);
|
||||
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
const lastBFSIds = tree.BFS();
|
||||
expect(lastBFSIds[0]).toBe(12);
|
||||
expect(lastBFSIds[1]).toBe(2);
|
||||
expect(lastBFSIds[2]).toBe(16);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
const lastBFSIds = tree.BFS();
|
||||
expect(lastBFSIds[0]).toBe(12);
|
||||
expect(lastBFSIds[1]).toBe(2);
|
||||
expect(lastBFSIds[2]).toBe(16);
|
||||
|
||||
const lastBFSNodes = tree.BFS('node');
|
||||
expect(lastBFSNodes[0].id).toBe(12);
|
||||
expect(lastBFSNodes[1].id).toBe(2);
|
||||
expect(lastBFSNodes[2].id).toBe(16);
|
||||
});
|
||||
const lastBFSNodes = tree.BFS('node');
|
||||
expect(lastBFSNodes[0].id).toBe(12);
|
||||
expect(lastBFSNodes[1].id).toBe(2);
|
||||
expect(lastBFSNodes[2].id).toBe(16);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,371 +1,371 @@
|
|||
import {BST, BSTNode} from 'bst-typed';
|
||||
|
||||
describe('Individual package BST operations test', () => {
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const bst = new BST();
|
||||
expect(bst).toBeInstanceOf(BST);
|
||||
bst.add(11, 11);
|
||||
bst.add(3, 3);
|
||||
const idsOrVals = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
bst.addMany(idsOrVals, idsOrVals);
|
||||
expect(bst.root).toBeInstanceOf(BSTNode);
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const bst = new BST();
|
||||
expect(bst).toBeInstanceOf(BST);
|
||||
bst.add(11, 11);
|
||||
bst.add(3, 3);
|
||||
const idsOrVals = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
bst.addMany(idsOrVals, idsOrVals);
|
||||
expect(bst.root).toBeInstanceOf(BSTNode);
|
||||
|
||||
if (bst.root) expect(bst.root.id).toBe(11);
|
||||
if (bst.root) expect(bst.root.id).toBe(11);
|
||||
|
||||
expect(bst.size).toBe(16);
|
||||
expect(bst.size).toBe(16);
|
||||
|
||||
expect(bst.has(6)).toBe(true);
|
||||
expect(bst.has(6)).toBe(true);
|
||||
|
||||
const node6 = bst.get(6);
|
||||
expect(node6 && bst.getHeight(6)).toBe(2);
|
||||
expect(node6 && bst.getDepth(6)).toBe(3);
|
||||
const node6 = bst.get(6);
|
||||
expect(node6 && bst.getHeight(6)).toBe(2);
|
||||
expect(node6 && bst.getDepth(6)).toBe(3);
|
||||
|
||||
const nodeId10 = bst.get(10);
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
const nodeId10 = bst.get(10);
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
|
||||
const nodeVal9 = bst.get(9, 'val');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
const nodeVal9 = bst.get(9, 'val');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
|
||||
|
||||
const leftMost = bst.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
const leftMost = bst.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
|
||||
const node15 = bst.get(15);
|
||||
const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && bst.subTreeSum(15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = bst.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
|
||||
const node11 = bst.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
|
||||
const dfsInorderNodes = bst.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
|
||||
bst.perfectlyBalance();
|
||||
expect(bst.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = bst.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = bst.remove(11, true);
|
||||
expect(removed11).toBeInstanceOf(Array);
|
||||
expect(removed11[0]).toBeDefined();
|
||||
expect(removed11[0].deleted).toBeDefined();
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(bst.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = bst.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
expect(removed1[0]).toBeDefined();
|
||||
expect(removed1[0].deleted).toBeDefined();
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = bst.remove(4, true);
|
||||
expect(removed4).toBeInstanceOf(Array);
|
||||
expect(removed4[0]).toBeDefined();
|
||||
expect(removed4[0].deleted).toBeDefined();
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = bst.remove(10, true);
|
||||
expect(removed10).toBeInstanceOf(Array);
|
||||
expect(removed10[0]).toBeDefined();
|
||||
expect(removed10[0].deleted).toBeDefined();
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = bst.remove(15, true);
|
||||
expect(removed15).toBeInstanceOf(Array);
|
||||
expect(removed15[0]).toBeDefined();
|
||||
expect(removed15[0].deleted).toBeDefined();
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = bst.remove(5, true);
|
||||
expect(removed5).toBeInstanceOf(Array);
|
||||
expect(removed5[0]).toBeDefined();
|
||||
expect(removed5[0].deleted).toBeDefined();
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = bst.remove(13, true);
|
||||
expect(removed13).toBeInstanceOf(Array);
|
||||
expect(removed13[0]).toBeDefined();
|
||||
expect(removed13[0].deleted).toBeDefined();
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = bst.remove(3, true);
|
||||
expect(removed3).toBeInstanceOf(Array);
|
||||
expect(removed3[0]).toBeDefined();
|
||||
expect(removed3[0].deleted).toBeDefined();
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = bst.remove(8, true);
|
||||
expect(removed8).toBeInstanceOf(Array);
|
||||
expect(removed8[0]).toBeDefined();
|
||||
expect(removed8[0].deleted).toBeDefined();
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = bst.remove(6, true);
|
||||
expect(removed6).toBeInstanceOf(Array);
|
||||
expect(removed6[0]).toBeDefined();
|
||||
expect(removed6[0].deleted).toBeDefined();
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(bst.remove(6, true).length).toBe(0);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = bst.remove(7, true);
|
||||
expect(removed7).toBeInstanceOf(Array);
|
||||
expect(removed7[0]).toBeDefined();
|
||||
expect(removed7[0].deleted).toBeDefined();
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = bst.remove(9, true);
|
||||
expect(removed9).toBeInstanceOf(Array);
|
||||
expect(removed9[0]).toBeDefined();
|
||||
expect(removed9[0].deleted).toBeDefined();
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed14 = bst.remove(14, true);
|
||||
expect(removed14).toBeInstanceOf(Array);
|
||||
expect(removed14[0]).toBeDefined();
|
||||
expect(removed14[0].deleted).toBeDefined();
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(2);
|
||||
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
|
||||
const bfsIDs = bst.BFS();
|
||||
expect(bfsIDs[0]).toBe(2);
|
||||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = bst.BFS('node');
|
||||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<BSTNode<{ id: number, keyA: number }>>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {id: 11, keyA: 11});
|
||||
objBST.add(3, {id: 3, keyA: 3});
|
||||
const values = [{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
|
||||
{id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2},
|
||||
{id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12},
|
||||
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
|
||||
{id: 10, keyA: 10}, {id: 5, keyA: 5}];
|
||||
|
||||
objBST.addMany(values.map(item => item.id), values);
|
||||
|
||||
expect(objBST.root).toBeInstanceOf(BSTNode);
|
||||
|
||||
if (objBST.root) expect(objBST.root.id).toBe(11);
|
||||
|
||||
expect(objBST.has(6)).toBe(true);
|
||||
|
||||
const node6 = objBST.get(6);
|
||||
expect(node6 && objBST.getHeight(node6)).toBe(2);
|
||||
expect(node6 && objBST.getDepth(node6)).toBe(3);
|
||||
|
||||
const nodeId10 = objBST.get(10, 'id');
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
|
||||
const nodeVal9 = objBST.get(9, 'id');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
|
||||
const leftMost = objBST.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
|
||||
const node15 = objBST.get(15);
|
||||
expect(node15?.val).toEqual({id: 15, keyA: 15});
|
||||
const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && objBST.subTreeSum(node15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = objBST.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
|
||||
const node11 = objBST.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
|
||||
const dfsInorderNodes = objBST.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
|
||||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = objBST.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = objBST.remove(11, true);
|
||||
expect(removed11).toBeInstanceOf(Array);
|
||||
expect(removed11[0]).toBeDefined();
|
||||
expect(removed11[0].deleted).toBeDefined();
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(node15 && objBST.getHeight(node15)).toBe(2);
|
||||
|
||||
const removed1 = objBST.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
expect(removed1[0]).toBeDefined();
|
||||
expect(removed1[0].deleted).toBeDefined();
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = objBST.remove(4, true);
|
||||
expect(removed4).toBeInstanceOf(Array);
|
||||
expect(removed4[0]).toBeDefined();
|
||||
expect(removed4[0].deleted).toBeDefined();
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = objBST.remove(10, true);
|
||||
expect(removed10).toBeInstanceOf(Array);
|
||||
expect(removed10[0]).toBeDefined();
|
||||
expect(removed10[0].deleted).toBeDefined();
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = objBST.remove(15, true);
|
||||
expect(removed15).toBeInstanceOf(Array);
|
||||
expect(removed15[0]).toBeDefined();
|
||||
expect(removed15[0].deleted).toBeDefined();
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = objBST.remove(5, true);
|
||||
expect(removed5).toBeInstanceOf(Array);
|
||||
expect(removed5[0]).toBeDefined();
|
||||
expect(removed5[0].deleted).toBeDefined();
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = objBST.remove(13, true);
|
||||
expect(removed13).toBeInstanceOf(Array);
|
||||
expect(removed13[0]).toBeDefined();
|
||||
expect(removed13[0].deleted).toBeDefined();
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = objBST.remove(3, true);
|
||||
expect(removed3).toBeInstanceOf(Array);
|
||||
expect(removed3[0]).toBeDefined();
|
||||
expect(removed3[0].deleted).toBeDefined();
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = objBST.remove(8, true);
|
||||
expect(removed8).toBeInstanceOf(Array);
|
||||
expect(removed8[0]).toBeDefined();
|
||||
expect(removed8[0].deleted).toBeDefined();
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = objBST.remove(6, true);
|
||||
expect(removed6).toBeInstanceOf(Array);
|
||||
expect(removed6[0]).toBeDefined();
|
||||
expect(removed6[0].deleted).toBeDefined();
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(objBST.remove(6, true).length).toBe(0);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = objBST.remove(7, true);
|
||||
expect(removed7).toBeInstanceOf(Array);
|
||||
expect(removed7[0]).toBeDefined();
|
||||
expect(removed7[0].deleted).toBeDefined();
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = objBST.remove(9, true);
|
||||
expect(removed9).toBeInstanceOf(Array);
|
||||
expect(removed9[0]).toBeDefined();
|
||||
expect(removed9[0].deleted).toBeDefined();
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed14 = objBST.remove(14, true);
|
||||
expect(removed14).toBeInstanceOf(Array);
|
||||
expect(removed14[0]).toBeDefined();
|
||||
expect(removed14[0].deleted).toBeDefined();
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(2);
|
||||
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
|
||||
const bfsIDs = objBST.BFS();
|
||||
expect(bfsIDs[0]).toBe(2);
|
||||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = objBST.BFS('node');
|
||||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
});
|
||||
const node15 = bst.get(15);
|
||||
const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && bst.subTreeSum(15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = bst.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
|
||||
const node11 = bst.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
|
||||
const dfsInorderNodes = bst.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
|
||||
bst.perfectlyBalance();
|
||||
expect(bst.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = bst.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = bst.remove(11, true);
|
||||
expect(removed11).toBeInstanceOf(Array);
|
||||
expect(removed11[0]).toBeDefined();
|
||||
expect(removed11[0].deleted).toBeDefined();
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(bst.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = bst.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
expect(removed1[0]).toBeDefined();
|
||||
expect(removed1[0].deleted).toBeDefined();
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = bst.remove(4, true);
|
||||
expect(removed4).toBeInstanceOf(Array);
|
||||
expect(removed4[0]).toBeDefined();
|
||||
expect(removed4[0].deleted).toBeDefined();
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = bst.remove(10, true);
|
||||
expect(removed10).toBeInstanceOf(Array);
|
||||
expect(removed10[0]).toBeDefined();
|
||||
expect(removed10[0].deleted).toBeDefined();
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = bst.remove(15, true);
|
||||
expect(removed15).toBeInstanceOf(Array);
|
||||
expect(removed15[0]).toBeDefined();
|
||||
expect(removed15[0].deleted).toBeDefined();
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = bst.remove(5, true);
|
||||
expect(removed5).toBeInstanceOf(Array);
|
||||
expect(removed5[0]).toBeDefined();
|
||||
expect(removed5[0].deleted).toBeDefined();
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = bst.remove(13, true);
|
||||
expect(removed13).toBeInstanceOf(Array);
|
||||
expect(removed13[0]).toBeDefined();
|
||||
expect(removed13[0].deleted).toBeDefined();
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = bst.remove(3, true);
|
||||
expect(removed3).toBeInstanceOf(Array);
|
||||
expect(removed3[0]).toBeDefined();
|
||||
expect(removed3[0].deleted).toBeDefined();
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = bst.remove(8, true);
|
||||
expect(removed8).toBeInstanceOf(Array);
|
||||
expect(removed8[0]).toBeDefined();
|
||||
expect(removed8[0].deleted).toBeDefined();
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = bst.remove(6, true);
|
||||
expect(removed6).toBeInstanceOf(Array);
|
||||
expect(removed6[0]).toBeDefined();
|
||||
expect(removed6[0].deleted).toBeDefined();
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(bst.remove(6, true).length).toBe(0);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = bst.remove(7, true);
|
||||
expect(removed7).toBeInstanceOf(Array);
|
||||
expect(removed7[0]).toBeDefined();
|
||||
expect(removed7[0].deleted).toBeDefined();
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = bst.remove(9, true);
|
||||
expect(removed9).toBeInstanceOf(Array);
|
||||
expect(removed9[0]).toBeDefined();
|
||||
expect(removed9[0].deleted).toBeDefined();
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed14 = bst.remove(14, true);
|
||||
expect(removed14).toBeInstanceOf(Array);
|
||||
expect(removed14[0]).toBeDefined();
|
||||
expect(removed14[0].deleted).toBeDefined();
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(2);
|
||||
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
|
||||
const bfsIDs = bst.BFS();
|
||||
expect(bfsIDs[0]).toBe(2);
|
||||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = bst.BFS('node');
|
||||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<BSTNode<{ id: number, keyA: number }>>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {id: 11, keyA: 11});
|
||||
objBST.add(3, {id: 3, keyA: 3});
|
||||
const values = [{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
|
||||
{id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2},
|
||||
{id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12},
|
||||
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
|
||||
{id: 10, keyA: 10}, {id: 5, keyA: 5}];
|
||||
|
||||
objBST.addMany(values.map(item => item.id), values);
|
||||
|
||||
expect(objBST.root).toBeInstanceOf(BSTNode);
|
||||
|
||||
if (objBST.root) expect(objBST.root.id).toBe(11);
|
||||
|
||||
expect(objBST.has(6)).toBe(true);
|
||||
|
||||
const node6 = objBST.get(6);
|
||||
expect(node6 && objBST.getHeight(node6)).toBe(2);
|
||||
expect(node6 && objBST.getDepth(node6)).toBe(3);
|
||||
|
||||
const nodeId10 = objBST.get(10, 'id');
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
|
||||
const nodeVal9 = objBST.get(9, 'id');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
|
||||
const leftMost = objBST.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
|
||||
const node15 = objBST.get(15);
|
||||
expect(node15?.val).toEqual({id: 15, keyA: 15});
|
||||
const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && objBST.subTreeSum(node15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = objBST.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
|
||||
const node11 = objBST.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
|
||||
const dfsInorderNodes = objBST.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
|
||||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = objBST.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = objBST.remove(11, true);
|
||||
expect(removed11).toBeInstanceOf(Array);
|
||||
expect(removed11[0]).toBeDefined();
|
||||
expect(removed11[0].deleted).toBeDefined();
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(node15 && objBST.getHeight(node15)).toBe(2);
|
||||
|
||||
const removed1 = objBST.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
expect(removed1[0]).toBeDefined();
|
||||
expect(removed1[0].deleted).toBeDefined();
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = objBST.remove(4, true);
|
||||
expect(removed4).toBeInstanceOf(Array);
|
||||
expect(removed4[0]).toBeDefined();
|
||||
expect(removed4[0].deleted).toBeDefined();
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = objBST.remove(10, true);
|
||||
expect(removed10).toBeInstanceOf(Array);
|
||||
expect(removed10[0]).toBeDefined();
|
||||
expect(removed10[0].deleted).toBeDefined();
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = objBST.remove(15, true);
|
||||
expect(removed15).toBeInstanceOf(Array);
|
||||
expect(removed15[0]).toBeDefined();
|
||||
expect(removed15[0].deleted).toBeDefined();
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = objBST.remove(5, true);
|
||||
expect(removed5).toBeInstanceOf(Array);
|
||||
expect(removed5[0]).toBeDefined();
|
||||
expect(removed5[0].deleted).toBeDefined();
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = objBST.remove(13, true);
|
||||
expect(removed13).toBeInstanceOf(Array);
|
||||
expect(removed13[0]).toBeDefined();
|
||||
expect(removed13[0].deleted).toBeDefined();
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = objBST.remove(3, true);
|
||||
expect(removed3).toBeInstanceOf(Array);
|
||||
expect(removed3[0]).toBeDefined();
|
||||
expect(removed3[0].deleted).toBeDefined();
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = objBST.remove(8, true);
|
||||
expect(removed8).toBeInstanceOf(Array);
|
||||
expect(removed8[0]).toBeDefined();
|
||||
expect(removed8[0].deleted).toBeDefined();
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = objBST.remove(6, true);
|
||||
expect(removed6).toBeInstanceOf(Array);
|
||||
expect(removed6[0]).toBeDefined();
|
||||
expect(removed6[0].deleted).toBeDefined();
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(objBST.remove(6, true).length).toBe(0);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = objBST.remove(7, true);
|
||||
expect(removed7).toBeInstanceOf(Array);
|
||||
expect(removed7[0]).toBeDefined();
|
||||
expect(removed7[0].deleted).toBeDefined();
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = objBST.remove(9, true);
|
||||
expect(removed9).toBeInstanceOf(Array);
|
||||
expect(removed9[0]).toBeDefined();
|
||||
expect(removed9[0].deleted).toBeDefined();
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed14 = objBST.remove(14, true);
|
||||
expect(removed14).toBeInstanceOf(Array);
|
||||
expect(removed14[0]).toBeDefined();
|
||||
expect(removed14[0].deleted).toBeDefined();
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(2);
|
||||
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
|
||||
const bfsIDs = objBST.BFS();
|
||||
expect(bfsIDs[0]).toBe(2);
|
||||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = objBST.BFS('node');
|
||||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
const {MinHeap} = require('heap-typed');
|
||||
|
||||
describe('JS Heap Operation Test', () => {
|
||||
it('should numeric heap work well', function () {
|
||||
const minNumHeap = new MinHeap();
|
||||
minNumHeap.add(1).add(6).add(2).add(0).add(5).add(9);
|
||||
expect(minNumHeap.poll()).toBe(0);
|
||||
expect(minNumHeap.poll()).toBe(1);
|
||||
expect(minNumHeap.peek()).toBe(2);
|
||||
expect(minNumHeap.toArray().length).toBe(4);
|
||||
expect(minNumHeap.toArray()[0]).toBe(2);
|
||||
expect(minNumHeap.toArray()[1]).toBe(5);
|
||||
expect(minNumHeap.toArray()[2]).toBe(9);
|
||||
expect(minNumHeap.toArray()[3]).toBe(6);
|
||||
it('should numeric heap work well', function () {
|
||||
const minNumHeap = new MinHeap();
|
||||
minNumHeap.add(1).add(6).add(2).add(0).add(5).add(9);
|
||||
expect(minNumHeap.poll()).toBe(0);
|
||||
expect(minNumHeap.poll()).toBe(1);
|
||||
expect(minNumHeap.peek()).toBe(2);
|
||||
expect(minNumHeap.toArray().length).toBe(4);
|
||||
expect(minNumHeap.toArray()[0]).toBe(2);
|
||||
expect(minNumHeap.toArray()[1]).toBe(5);
|
||||
expect(minNumHeap.toArray()[2]).toBe(9);
|
||||
expect(minNumHeap.toArray()[3]).toBe(6);
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,31 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>CDN Test</title>
|
||||
<meta charset="UTF-8">
|
||||
<title>CDN Test</title>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/data-structure-typed/dist/bundle.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/data-structure-typed/dist/bundle.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<ul class="modules">
|
||||
<div id="app">
|
||||
<ul class="modules">
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<script defer>
|
||||
const $modules = document.querySelector('.modules');
|
||||
const $avlTree = document.createElement('li');
|
||||
const $avlTreeSpan = document.createElement('span');
|
||||
$avlTreeSpan.innerText = 'AVLTree';
|
||||
$avlTree.append($avlTreeSpan);
|
||||
const {AVLTree} = dataStructureTyped;
|
||||
const avlTree = new AVLTree();
|
||||
</ul>
|
||||
</div>
|
||||
<script defer>
|
||||
const $modules = document.querySelector('.modules');
|
||||
const $avlTree = document.createElement('li');
|
||||
const $avlTreeSpan = document.createElement('span');
|
||||
$avlTreeSpan.innerText = 'AVLTree';
|
||||
$avlTree.append($avlTreeSpan);
|
||||
const {AVLTree, ArrayQueue} = dataStructureTyped;
|
||||
const avlTree = new AVLTree();
|
||||
|
||||
avlTree.add(1, 1);
|
||||
console.log(avlTree.BFS());
|
||||
$modules.append($avlTree);
|
||||
</script>
|
||||
avlTree.add(1, 1);
|
||||
console.log(avlTree.BFS());
|
||||
$modules.append($avlTree);
|
||||
|
||||
|
||||
const queue = new ArrayQueue();
|
||||
for (let i = 0; i < 1000000; i++) {
|
||||
queue.enqueue(i);
|
||||
}
|
||||
let last = 0;
|
||||
const startTime = performance.now();
|
||||
|
||||
for (let i = 0; i < 1000000; i++) {
|
||||
last = queue.dequeue();
|
||||
}
|
||||
|
||||
console.log(performance.now() - startTime)
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
|
@ -1,111 +1,111 @@
|
|||
import {AVLTree} from '../../../../src';
|
||||
|
||||
describe('AVL Tree Test', () => {
|
||||
it('should perform various operations on a AVL Tree', () => {
|
||||
it('should perform various operations on a AVL Tree', () => {
|
||||
|
||||
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
const tree = new AVLTree();
|
||||
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
const tree = new AVLTree();
|
||||
|
||||
for (const i of arr) tree.add(i, i);
|
||||
for (const i of arr) tree.add(i, i);
|
||||
|
||||
const node6 = tree.get(6);
|
||||
const node6 = tree.get(6);
|
||||
|
||||
expect(node6 && tree.getHeight(node6)).toBe(3);
|
||||
expect(node6 && tree.getDepth(node6)).toBe(1);
|
||||
expect(node6 && tree.getHeight(node6)).toBe(3);
|
||||
expect(node6 && tree.getDepth(node6)).toBe(1);
|
||||
|
||||
const getNodeById = tree.get(10, 'id');
|
||||
expect(getNodeById?.id).toBe(10);
|
||||
const getNodeById = tree.get(10, 'id');
|
||||
expect(getNodeById?.id).toBe(10);
|
||||
|
||||
|
||||
const getMinNodeByRoot = tree.getLeftMost();
|
||||
expect(getMinNodeByRoot?.id).toBe(1);
|
||||
const getMinNodeByRoot = tree.getLeftMost();
|
||||
expect(getMinNodeByRoot?.id).toBe(1);
|
||||
|
||||
const node15 = tree.get(15);
|
||||
const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
|
||||
expect(getMinNodeBySpecificNode?.id).toBe(12);
|
||||
const node15 = tree.get(15);
|
||||
const getMinNodeBySpecificNode = node15 && tree.getLeftMost(node15);
|
||||
expect(getMinNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && tree.subTreeSum(node15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
const subTreeSum = node15 && tree.subTreeSum(node15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = tree.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
const lesserSum = tree.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
|
||||
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
||||
expect(node15?.val).toBe(15);
|
||||
// node15 has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
||||
expect(node15?.val).toBe(15);
|
||||
|
||||
const dfs = tree.DFS('in', 'node');
|
||||
expect(dfs[0].id).toBe(1);
|
||||
expect(dfs[dfs.length - 1].id).toBe(16);
|
||||
const dfs = tree.DFS('in', 'node');
|
||||
expect(dfs[0].id).toBe(1);
|
||||
expect(dfs[dfs.length - 1].id).toBe(16);
|
||||
|
||||
tree.perfectlyBalance();
|
||||
const bfs = tree.BFS('node');
|
||||
expect(tree.isPerfectlyBalanced()).toBe(true);
|
||||
expect(bfs[0].id).toBe(8);
|
||||
expect(bfs[bfs.length - 1].id).toBe(16);
|
||||
tree.perfectlyBalance();
|
||||
const bfs = tree.BFS('node');
|
||||
expect(tree.isPerfectlyBalanced()).toBe(true);
|
||||
expect(bfs[0].id).toBe(8);
|
||||
expect(bfs[bfs.length - 1].id).toBe(16);
|
||||
|
||||
expect(tree.remove(11, true)[0].deleted?.id).toBe(11);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(node15 && tree.getHeight(node15)).toBe(2);
|
||||
expect(tree.remove(11, true)[0].deleted?.id).toBe(11);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(node15 && tree.getHeight(node15)).toBe(2);
|
||||
|
||||
expect(tree.remove(1, true)[0].deleted?.id).toBe(1);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(4);
|
||||
expect(tree.remove(1, true)[0].deleted?.id).toBe(1);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(4);
|
||||
|
||||
expect(tree.remove(4, true)[0].deleted?.id).toBe(4);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(4);
|
||||
expect(tree.remove(4, true)[0].deleted?.id).toBe(4);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(4);
|
||||
|
||||
expect(tree.remove(10, true)[0].deleted?.id).toBe(10);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(10, true)[0].deleted?.id).toBe(10);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(15, true)[0].deleted?.id).toBe(15);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.remove(15, true)[0].deleted?.id).toBe(15);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(5, true)[0].deleted?.id).toBe(5);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(5, true)[0].deleted?.id).toBe(5);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(13, true)[0].deleted?.id).toBe(13);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(13, true)[0].deleted?.id).toBe(13);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(3, true)[0].deleted?.id).toBe(3);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(3, true)[0].deleted?.id).toBe(3);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(8, true)[0].deleted?.id).toBe(8);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
expect(tree.remove(8, true)[0].deleted?.id).toBe(8);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(3);
|
||||
|
||||
expect(tree.remove(6, true)[0].deleted?.id).toBe(6);
|
||||
expect(tree.remove(6, true).length).toBe(0);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
expect(tree.remove(6, true)[0].deleted?.id).toBe(6);
|
||||
expect(tree.remove(6, true).length).toBe(0);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
|
||||
expect(tree.remove(7, true)[0].deleted?.id).toBe(7);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
expect(tree.remove(7, true)[0].deleted?.id).toBe(7);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
|
||||
expect(tree.remove(9, true)[0].deleted?.id).toBe(9);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
expect(tree.remove(14, true)[0].deleted?.id).toBe(14);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(1);
|
||||
expect(tree.remove(9, true)[0].deleted?.id).toBe(9);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(2);
|
||||
expect(tree.remove(14, true)[0].deleted?.id).toBe(14);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
expect(tree.getHeight()).toBe(1);
|
||||
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
const lastBFSIds = tree.BFS();
|
||||
expect(lastBFSIds[0]).toBe(12);
|
||||
expect(lastBFSIds[1]).toBe(2);
|
||||
expect(lastBFSIds[2]).toBe(16);
|
||||
expect(tree.isAVLBalanced()).toBe(true);
|
||||
const lastBFSIds = tree.BFS();
|
||||
expect(lastBFSIds[0]).toBe(12);
|
||||
expect(lastBFSIds[1]).toBe(2);
|
||||
expect(lastBFSIds[2]).toBe(16);
|
||||
|
||||
const lastBFSNodes = tree.BFS('node');
|
||||
expect(lastBFSNodes[0].id).toBe(12);
|
||||
expect(lastBFSNodes[1].id).toBe(2);
|
||||
expect(lastBFSNodes[2].id).toBe(16);
|
||||
});
|
||||
const lastBFSNodes = tree.BFS('node');
|
||||
expect(lastBFSNodes[0].id).toBe(12);
|
||||
expect(lastBFSNodes[1].id).toBe(2);
|
||||
expect(lastBFSNodes[2].id).toBe(16);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,371 +1,371 @@
|
|||
import {BST, BSTNode} from '../../../../src';
|
||||
|
||||
describe('BST operations test', () => {
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const bst = new BST();
|
||||
expect(bst).toBeInstanceOf(BST);
|
||||
bst.add(11, 11);
|
||||
bst.add(3, 3);
|
||||
const idsAndValues = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
bst.addMany(idsAndValues, idsAndValues);
|
||||
expect(bst.root).toBeInstanceOf(BSTNode);
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const bst = new BST();
|
||||
expect(bst).toBeInstanceOf(BST);
|
||||
bst.add(11, 11);
|
||||
bst.add(3, 3);
|
||||
const idsAndValues = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
bst.addMany(idsAndValues, idsAndValues);
|
||||
expect(bst.root).toBeInstanceOf(BSTNode);
|
||||
|
||||
if (bst.root) expect(bst.root.id).toBe(11);
|
||||
if (bst.root) expect(bst.root.id).toBe(11);
|
||||
|
||||
expect(bst.size).toBe(16);
|
||||
expect(bst.size).toBe(16);
|
||||
|
||||
expect(bst.has(6)).toBe(true);
|
||||
expect(bst.has(6)).toBe(true);
|
||||
|
||||
const node6 = bst.get(6);
|
||||
expect(node6 && bst.getHeight(6)).toBe(2);
|
||||
expect(node6 && bst.getDepth(6)).toBe(3);
|
||||
const node6 = bst.get(6);
|
||||
expect(node6 && bst.getHeight(6)).toBe(2);
|
||||
expect(node6 && bst.getDepth(6)).toBe(3);
|
||||
|
||||
const nodeId10 = bst.get(10);
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
const nodeId10 = bst.get(10);
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
|
||||
const nodeVal9 = bst.get(9, 'val');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
const nodeVal9 = bst.get(9, 'val');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
|
||||
|
||||
const leftMost = bst.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
const leftMost = bst.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
|
||||
const node15 = bst.get(15);
|
||||
const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && bst.subTreeSum(15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = bst.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
|
||||
const node11 = bst.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
|
||||
const dfsInorderNodes = bst.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
|
||||
bst.perfectlyBalance();
|
||||
expect(bst.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = bst.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = bst.remove(11, true);
|
||||
expect(removed11).toBeInstanceOf(Array);
|
||||
expect(removed11[0]).toBeDefined();
|
||||
expect(removed11[0].deleted).toBeDefined();
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(bst.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = bst.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
expect(removed1[0]).toBeDefined();
|
||||
expect(removed1[0].deleted).toBeDefined();
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = bst.remove(4, true);
|
||||
expect(removed4).toBeInstanceOf(Array);
|
||||
expect(removed4[0]).toBeDefined();
|
||||
expect(removed4[0].deleted).toBeDefined();
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = bst.remove(10, true);
|
||||
expect(removed10).toBeInstanceOf(Array);
|
||||
expect(removed10[0]).toBeDefined();
|
||||
expect(removed10[0].deleted).toBeDefined();
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = bst.remove(15, true);
|
||||
expect(removed15).toBeInstanceOf(Array);
|
||||
expect(removed15[0]).toBeDefined();
|
||||
expect(removed15[0].deleted).toBeDefined();
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = bst.remove(5, true);
|
||||
expect(removed5).toBeInstanceOf(Array);
|
||||
expect(removed5[0]).toBeDefined();
|
||||
expect(removed5[0].deleted).toBeDefined();
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = bst.remove(13, true);
|
||||
expect(removed13).toBeInstanceOf(Array);
|
||||
expect(removed13[0]).toBeDefined();
|
||||
expect(removed13[0].deleted).toBeDefined();
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = bst.remove(3, true);
|
||||
expect(removed3).toBeInstanceOf(Array);
|
||||
expect(removed3[0]).toBeDefined();
|
||||
expect(removed3[0].deleted).toBeDefined();
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = bst.remove(8, true);
|
||||
expect(removed8).toBeInstanceOf(Array);
|
||||
expect(removed8[0]).toBeDefined();
|
||||
expect(removed8[0].deleted).toBeDefined();
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = bst.remove(6, true);
|
||||
expect(removed6).toBeInstanceOf(Array);
|
||||
expect(removed6[0]).toBeDefined();
|
||||
expect(removed6[0].deleted).toBeDefined();
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(bst.remove(6, true).length).toBe(0);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = bst.remove(7, true);
|
||||
expect(removed7).toBeInstanceOf(Array);
|
||||
expect(removed7[0]).toBeDefined();
|
||||
expect(removed7[0].deleted).toBeDefined();
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = bst.remove(9, true);
|
||||
expect(removed9).toBeInstanceOf(Array);
|
||||
expect(removed9[0]).toBeDefined();
|
||||
expect(removed9[0].deleted).toBeDefined();
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed14 = bst.remove(14, true);
|
||||
expect(removed14).toBeInstanceOf(Array);
|
||||
expect(removed14[0]).toBeDefined();
|
||||
expect(removed14[0].deleted).toBeDefined();
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(2);
|
||||
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
|
||||
const bfsIDs = bst.BFS();
|
||||
expect(bfsIDs[0]).toBe(2);
|
||||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = bst.BFS('node');
|
||||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<BSTNode<{ id: number, keyA: number }>>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {id: 11, keyA: 11});
|
||||
objBST.add(3, {id: 3, keyA: 3});
|
||||
const values = [{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
|
||||
{id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2},
|
||||
{id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12},
|
||||
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
|
||||
{id: 10, keyA: 10}, {id: 5, keyA: 5}];
|
||||
|
||||
objBST.addMany(values.map(item => item.id), values);
|
||||
|
||||
expect(objBST.root).toBeInstanceOf(BSTNode);
|
||||
|
||||
if (objBST.root) expect(objBST.root.id).toBe(11);
|
||||
|
||||
expect(objBST.has(6)).toBe(true);
|
||||
|
||||
const node6 = objBST.get(6);
|
||||
expect(node6 && objBST.getHeight(node6)).toBe(2);
|
||||
expect(node6 && objBST.getDepth(node6)).toBe(3);
|
||||
|
||||
const nodeId10 = objBST.get(10, 'id');
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
|
||||
const nodeVal9 = objBST.get(9, 'id');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
|
||||
const leftMost = objBST.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
|
||||
const node15 = objBST.get(15);
|
||||
expect(node15?.val).toEqual({id: 15, keyA: 15});
|
||||
const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && objBST.subTreeSum(node15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = objBST.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
|
||||
const node11 = objBST.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
|
||||
const dfsInorderNodes = objBST.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
|
||||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = objBST.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = objBST.remove(11, true);
|
||||
expect(removed11).toBeInstanceOf(Array);
|
||||
expect(removed11[0]).toBeDefined();
|
||||
expect(removed11[0].deleted).toBeDefined();
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(node15 && objBST.getHeight(node15)).toBe(2);
|
||||
|
||||
const removed1 = objBST.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
expect(removed1[0]).toBeDefined();
|
||||
expect(removed1[0].deleted).toBeDefined();
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = objBST.remove(4, true);
|
||||
expect(removed4).toBeInstanceOf(Array);
|
||||
expect(removed4[0]).toBeDefined();
|
||||
expect(removed4[0].deleted).toBeDefined();
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = objBST.remove(10, true);
|
||||
expect(removed10).toBeInstanceOf(Array);
|
||||
expect(removed10[0]).toBeDefined();
|
||||
expect(removed10[0].deleted).toBeDefined();
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = objBST.remove(15, true);
|
||||
expect(removed15).toBeInstanceOf(Array);
|
||||
expect(removed15[0]).toBeDefined();
|
||||
expect(removed15[0].deleted).toBeDefined();
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = objBST.remove(5, true);
|
||||
expect(removed5).toBeInstanceOf(Array);
|
||||
expect(removed5[0]).toBeDefined();
|
||||
expect(removed5[0].deleted).toBeDefined();
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = objBST.remove(13, true);
|
||||
expect(removed13).toBeInstanceOf(Array);
|
||||
expect(removed13[0]).toBeDefined();
|
||||
expect(removed13[0].deleted).toBeDefined();
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = objBST.remove(3, true);
|
||||
expect(removed3).toBeInstanceOf(Array);
|
||||
expect(removed3[0]).toBeDefined();
|
||||
expect(removed3[0].deleted).toBeDefined();
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = objBST.remove(8, true);
|
||||
expect(removed8).toBeInstanceOf(Array);
|
||||
expect(removed8[0]).toBeDefined();
|
||||
expect(removed8[0].deleted).toBeDefined();
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = objBST.remove(6, true);
|
||||
expect(removed6).toBeInstanceOf(Array);
|
||||
expect(removed6[0]).toBeDefined();
|
||||
expect(removed6[0].deleted).toBeDefined();
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(objBST.remove(6, true).length).toBe(0);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = objBST.remove(7, true);
|
||||
expect(removed7).toBeInstanceOf(Array);
|
||||
expect(removed7[0]).toBeDefined();
|
||||
expect(removed7[0].deleted).toBeDefined();
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = objBST.remove(9, true);
|
||||
expect(removed9).toBeInstanceOf(Array);
|
||||
expect(removed9[0]).toBeDefined();
|
||||
expect(removed9[0].deleted).toBeDefined();
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed14 = objBST.remove(14, true);
|
||||
expect(removed14).toBeInstanceOf(Array);
|
||||
expect(removed14[0]).toBeDefined();
|
||||
expect(removed14[0].deleted).toBeDefined();
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(2);
|
||||
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
|
||||
const bfsIDs = objBST.BFS();
|
||||
expect(bfsIDs[0]).toBe(2);
|
||||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = objBST.BFS('node');
|
||||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
});
|
||||
const node15 = bst.get(15);
|
||||
const minNodeBySpecificNode = node15 && bst.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && bst.subTreeSum(15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = bst.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
|
||||
const node11 = bst.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
|
||||
const dfsInorderNodes = bst.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
|
||||
bst.perfectlyBalance();
|
||||
expect(bst.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = bst.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = bst.remove(11, true);
|
||||
expect(removed11).toBeInstanceOf(Array);
|
||||
expect(removed11[0]).toBeDefined();
|
||||
expect(removed11[0].deleted).toBeDefined();
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(bst.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = bst.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
expect(removed1[0]).toBeDefined();
|
||||
expect(removed1[0].deleted).toBeDefined();
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = bst.remove(4, true);
|
||||
expect(removed4).toBeInstanceOf(Array);
|
||||
expect(removed4[0]).toBeDefined();
|
||||
expect(removed4[0].deleted).toBeDefined();
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = bst.remove(10, true);
|
||||
expect(removed10).toBeInstanceOf(Array);
|
||||
expect(removed10[0]).toBeDefined();
|
||||
expect(removed10[0].deleted).toBeDefined();
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = bst.remove(15, true);
|
||||
expect(removed15).toBeInstanceOf(Array);
|
||||
expect(removed15[0]).toBeDefined();
|
||||
expect(removed15[0].deleted).toBeDefined();
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = bst.remove(5, true);
|
||||
expect(removed5).toBeInstanceOf(Array);
|
||||
expect(removed5[0]).toBeDefined();
|
||||
expect(removed5[0].deleted).toBeDefined();
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = bst.remove(13, true);
|
||||
expect(removed13).toBeInstanceOf(Array);
|
||||
expect(removed13[0]).toBeDefined();
|
||||
expect(removed13[0].deleted).toBeDefined();
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = bst.remove(3, true);
|
||||
expect(removed3).toBeInstanceOf(Array);
|
||||
expect(removed3[0]).toBeDefined();
|
||||
expect(removed3[0].deleted).toBeDefined();
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = bst.remove(8, true);
|
||||
expect(removed8).toBeInstanceOf(Array);
|
||||
expect(removed8[0]).toBeDefined();
|
||||
expect(removed8[0].deleted).toBeDefined();
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = bst.remove(6, true);
|
||||
expect(removed6).toBeInstanceOf(Array);
|
||||
expect(removed6[0]).toBeDefined();
|
||||
expect(removed6[0].deleted).toBeDefined();
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(bst.remove(6, true).length).toBe(0);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = bst.remove(7, true);
|
||||
expect(removed7).toBeInstanceOf(Array);
|
||||
expect(removed7[0]).toBeDefined();
|
||||
expect(removed7[0].deleted).toBeDefined();
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = bst.remove(9, true);
|
||||
expect(removed9).toBeInstanceOf(Array);
|
||||
expect(removed9[0]).toBeDefined();
|
||||
expect(removed9[0].deleted).toBeDefined();
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(3);
|
||||
|
||||
const removed14 = bst.remove(14, true);
|
||||
expect(removed14).toBeInstanceOf(Array);
|
||||
expect(removed14[0]).toBeDefined();
|
||||
expect(removed14[0].deleted).toBeDefined();
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
expect(bst.getHeight()).toBe(2);
|
||||
|
||||
|
||||
expect(bst.isAVLBalanced()).toBe(false);
|
||||
|
||||
const bfsIDs = bst.BFS();
|
||||
expect(bfsIDs[0]).toBe(2);
|
||||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = bst.BFS('node');
|
||||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<BSTNode<{ id: number, keyA: number }>>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {id: 11, keyA: 11});
|
||||
objBST.add(3, {id: 3, keyA: 3});
|
||||
const values = [{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
|
||||
{id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2},
|
||||
{id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12},
|
||||
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
|
||||
{id: 10, keyA: 10}, {id: 5, keyA: 5}];
|
||||
|
||||
objBST.addMany(values.map(item => item.id), values);
|
||||
|
||||
expect(objBST.root).toBeInstanceOf(BSTNode);
|
||||
|
||||
if (objBST.root) expect(objBST.root.id).toBe(11);
|
||||
|
||||
expect(objBST.has(6)).toBe(true);
|
||||
|
||||
const node6 = objBST.get(6);
|
||||
expect(node6 && objBST.getHeight(node6)).toBe(2);
|
||||
expect(node6 && objBST.getDepth(node6)).toBe(3);
|
||||
|
||||
const nodeId10 = objBST.get(10, 'id');
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
|
||||
const nodeVal9 = objBST.get(9, 'id');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
|
||||
const leftMost = objBST.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
|
||||
const node15 = objBST.get(15);
|
||||
expect(node15?.val).toEqual({id: 15, keyA: 15});
|
||||
const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && objBST.subTreeSum(node15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
|
||||
const lesserSum = objBST.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
expect(node15).toBeInstanceOf(BSTNode);
|
||||
|
||||
const node11 = objBST.get(11);
|
||||
expect(node11).toBeInstanceOf(BSTNode);
|
||||
|
||||
const dfsInorderNodes = objBST.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
|
||||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = objBST.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = objBST.remove(11, true);
|
||||
expect(removed11).toBeInstanceOf(Array);
|
||||
expect(removed11[0]).toBeDefined();
|
||||
expect(removed11[0].deleted).toBeDefined();
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(node15 && objBST.getHeight(node15)).toBe(2);
|
||||
|
||||
const removed1 = objBST.remove(1, true);
|
||||
expect(removed1).toBeInstanceOf(Array);
|
||||
expect(removed1[0]).toBeDefined();
|
||||
expect(removed1[0].deleted).toBeDefined();
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = objBST.remove(4, true);
|
||||
expect(removed4).toBeInstanceOf(Array);
|
||||
expect(removed4[0]).toBeDefined();
|
||||
expect(removed4[0].deleted).toBeDefined();
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = objBST.remove(10, true);
|
||||
expect(removed10).toBeInstanceOf(Array);
|
||||
expect(removed10[0]).toBeDefined();
|
||||
expect(removed10[0].deleted).toBeDefined();
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = objBST.remove(15, true);
|
||||
expect(removed15).toBeInstanceOf(Array);
|
||||
expect(removed15[0]).toBeDefined();
|
||||
expect(removed15[0].deleted).toBeDefined();
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = objBST.remove(5, true);
|
||||
expect(removed5).toBeInstanceOf(Array);
|
||||
expect(removed5[0]).toBeDefined();
|
||||
expect(removed5[0].deleted).toBeDefined();
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = objBST.remove(13, true);
|
||||
expect(removed13).toBeInstanceOf(Array);
|
||||
expect(removed13[0]).toBeDefined();
|
||||
expect(removed13[0].deleted).toBeDefined();
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = objBST.remove(3, true);
|
||||
expect(removed3).toBeInstanceOf(Array);
|
||||
expect(removed3[0]).toBeDefined();
|
||||
expect(removed3[0].deleted).toBeDefined();
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = objBST.remove(8, true);
|
||||
expect(removed8).toBeInstanceOf(Array);
|
||||
expect(removed8[0]).toBeDefined();
|
||||
expect(removed8[0].deleted).toBeDefined();
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(objBST.isAVLBalanced()).toBe(true);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = objBST.remove(6, true);
|
||||
expect(removed6).toBeInstanceOf(Array);
|
||||
expect(removed6[0]).toBeDefined();
|
||||
expect(removed6[0].deleted).toBeDefined();
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(objBST.remove(6, true).length).toBe(0);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = objBST.remove(7, true);
|
||||
expect(removed7).toBeInstanceOf(Array);
|
||||
expect(removed7[0]).toBeDefined();
|
||||
expect(removed7[0].deleted).toBeDefined();
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = objBST.remove(9, true);
|
||||
expect(removed9).toBeInstanceOf(Array);
|
||||
expect(removed9[0]).toBeDefined();
|
||||
expect(removed9[0].deleted).toBeDefined();
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(3);
|
||||
|
||||
const removed14 = objBST.remove(14, true);
|
||||
expect(removed14).toBeInstanceOf(Array);
|
||||
expect(removed14[0]).toBeDefined();
|
||||
expect(removed14[0].deleted).toBeDefined();
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
expect(objBST.getHeight()).toBe(2);
|
||||
|
||||
|
||||
expect(objBST.isAVLBalanced()).toBe(false);
|
||||
|
||||
const bfsIDs = objBST.BFS();
|
||||
expect(bfsIDs[0]).toBe(2);
|
||||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = objBST.BFS('node');
|
||||
expect(bfsNodes[0].id).toBe(2);
|
||||
expect(bfsNodes[1].id).toBe(12);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
import {AVLTree, BST, BSTNode} from '../../../../src';
|
||||
|
||||
describe('Overall BinaryTree Test', () => {
|
||||
it('should perform various operations on BinaryTree', () => {
|
||||
const bst = new BST();
|
||||
bst.add(11);
|
||||
bst.add(3);
|
||||
bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
|
||||
bst.size === 16; // true
|
||||
expect(bst.size).toBe(16); // true
|
||||
bst.has(6); // true
|
||||
expect(bst.has(6)).toBe(true); // true
|
||||
const node6 = bst.get(6);
|
||||
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?.id === 1; // true
|
||||
expect(leftMost?.id).toBe(1);
|
||||
bst.remove(6);
|
||||
bst.get(6); // null
|
||||
expect(bst.get(6)).toBeNull();
|
||||
bst.isAVLBalanced(); // true or false
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
const bfsIDs = bst.BFS();
|
||||
bfsIDs[0] === 11; // true
|
||||
expect(bfsIDs[0]).toBe(11);
|
||||
it('should perform various operations on BinaryTree', () => {
|
||||
const bst = new BST();
|
||||
bst.add(11);
|
||||
bst.add(3);
|
||||
bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
|
||||
bst.size === 16; // true
|
||||
expect(bst.size).toBe(16); // true
|
||||
bst.has(6); // true
|
||||
expect(bst.has(6)).toBe(true); // true
|
||||
const node6 = bst.get(6);
|
||||
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?.id === 1; // true
|
||||
expect(leftMost?.id).toBe(1);
|
||||
bst.remove(6);
|
||||
bst.get(6); // null
|
||||
expect(bst.get(6)).toBeNull();
|
||||
bst.isAVLBalanced(); // true or false
|
||||
expect(bst.isAVLBalanced()).toBe(true);
|
||||
const bfsIDs = bst.BFS();
|
||||
bfsIDs[0] === 11; // true
|
||||
expect(bfsIDs[0]).toBe(11);
|
||||
|
||||
const objBST = new BST<BSTNode<{ id: number, keyA: number }>>();
|
||||
objBST.add(11, {id: 11, keyA: 11});
|
||||
objBST.add(3, {id: 3, keyA: 3});
|
||||
const objBST = new BST<BSTNode<{ id: number, keyA: number }>>();
|
||||
objBST.add(11, {id: 11, keyA: 11});
|
||||
objBST.add(3, {id: 3, keyA: 3});
|
||||
|
||||
objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5],
|
||||
[
|
||||
{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
|
||||
{id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2},
|
||||
{id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12},
|
||||
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
|
||||
{id: 10, keyA: 10}, {id: 5, keyA: 5}
|
||||
]);
|
||||
objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5],
|
||||
[
|
||||
{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
|
||||
{id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2},
|
||||
{id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12},
|
||||
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
|
||||
{id: 10, keyA: 10}, {id: 5, keyA: 5}
|
||||
]);
|
||||
|
||||
objBST.remove(11);
|
||||
objBST.remove(11);
|
||||
|
||||
|
||||
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.remove(10);
|
||||
avlTree.isAVLBalanced(); // true
|
||||
expect(avlTree.isAVLBalanced()).toBe(true); // true
|
||||
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.remove(10);
|
||||
avlTree.isAVLBalanced(); // true
|
||||
expect(avlTree.isAVLBalanced()).toBe(true); // true
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,405 +1,405 @@
|
|||
import {TreeMultiset, TreeMultisetNode} from '../../../../src';
|
||||
|
||||
describe('TreeMultiset operations test', () => {
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const treeMultiset = new TreeMultiset();
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const treeMultiset = new TreeMultiset();
|
||||
|
||||
expect(treeMultiset instanceof TreeMultiset);
|
||||
treeMultiset.add(11, 11);
|
||||
treeMultiset.add(3, 3);
|
||||
const idAndValues = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
treeMultiset.addMany(idAndValues, idAndValues);
|
||||
expect(treeMultiset.root instanceof TreeMultisetNode);
|
||||
expect(treeMultiset instanceof TreeMultiset);
|
||||
treeMultiset.add(11, 11);
|
||||
treeMultiset.add(3, 3);
|
||||
const idAndValues = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
treeMultiset.addMany(idAndValues, idAndValues);
|
||||
expect(treeMultiset.root instanceof TreeMultisetNode);
|
||||
|
||||
if (treeMultiset.root) expect(treeMultiset.root.id == 11);
|
||||
if (treeMultiset.root) expect(treeMultiset.root.id == 11);
|
||||
|
||||
expect(treeMultiset.size).toBe(16);
|
||||
expect(treeMultiset.count).toBe(18);
|
||||
expect(treeMultiset.BFS('id'))
|
||||
expect(treeMultiset.size).toBe(16);
|
||||
expect(treeMultiset.count).toBe(18);
|
||||
expect(treeMultiset.BFS('id'))
|
||||
|
||||
expect(treeMultiset.has(6));
|
||||
expect(treeMultiset.has(6));
|
||||
|
||||
expect(treeMultiset.getHeight(6)).toBe(3);
|
||||
expect(treeMultiset.getDepth(6)).toBe(1);
|
||||
const nodeId10 = treeMultiset.get(10);
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
expect(treeMultiset.getHeight(6)).toBe(3);
|
||||
expect(treeMultiset.getDepth(6)).toBe(1);
|
||||
const nodeId10 = treeMultiset.get(10);
|
||||
expect(nodeId10?.id).toBe(10);
|
||||
|
||||
const nodeVal9 = treeMultiset.get(9, 'val');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
const nodeVal9 = treeMultiset.get(9, 'val');
|
||||
expect(nodeVal9?.id).toBe(9);
|
||||
|
||||
const nodesByCount1 = treeMultiset.getNodesByCount(1);
|
||||
expect(nodesByCount1.length).toBe(14);
|
||||
const nodesByCount1 = treeMultiset.getNodesByCount(1);
|
||||
expect(nodesByCount1.length).toBe(14);
|
||||
|
||||
const nodesByCount2 = treeMultiset.getNodesByCount(2);
|
||||
expect(nodesByCount2.length).toBe(2);
|
||||
const leftMost = treeMultiset.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
const nodesByCount2 = treeMultiset.getNodesByCount(2);
|
||||
expect(nodesByCount2.length).toBe(2);
|
||||
const leftMost = treeMultiset.getLeftMost();
|
||||
expect(leftMost?.id).toBe(1);
|
||||
|
||||
const node15 = treeMultiset.get(15);
|
||||
const minNodeBySpecificNode = node15 && treeMultiset.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
const node15 = treeMultiset.get(15);
|
||||
const minNodeBySpecificNode = node15 && treeMultiset.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
|
||||
const subTreeSum = node15 && treeMultiset.subTreeSum(15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
const lesserSum = treeMultiset.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
const subTreeSum = node15 && treeMultiset.subTreeSum(15);
|
||||
expect(subTreeSum).toBe(70);
|
||||
const lesserSum = treeMultiset.lesserSum(10);
|
||||
expect(lesserSum).toBe(45);
|
||||
|
||||
|
||||
expect(node15 instanceof TreeMultisetNode);
|
||||
if (node15 instanceof TreeMultisetNode) {
|
||||
const subTreeAdd = treeMultiset.subTreeAddCount(15, 1);
|
||||
expect(subTreeAdd);
|
||||
}
|
||||
const node11 = treeMultiset.get(11);
|
||||
expect(node11 instanceof TreeMultisetNode);
|
||||
if (node11 instanceof TreeMultisetNode) {
|
||||
const allGreaterNodesAdded = treeMultiset.allGreaterNodesAddCount(11, 2);
|
||||
expect(allGreaterNodesAdded);
|
||||
}
|
||||
expect(node15 instanceof TreeMultisetNode);
|
||||
if (node15 instanceof TreeMultisetNode) {
|
||||
const subTreeAdd = treeMultiset.subTreeAddCount(15, 1);
|
||||
expect(subTreeAdd);
|
||||
}
|
||||
const node11 = treeMultiset.get(11);
|
||||
expect(node11 instanceof TreeMultisetNode);
|
||||
if (node11 instanceof TreeMultisetNode) {
|
||||
const allGreaterNodesAdded = treeMultiset.allGreaterNodesAddCount(11, 2);
|
||||
expect(allGreaterNodesAdded);
|
||||
}
|
||||
|
||||
const dfsInorderNodes = treeMultiset.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
expect(treeMultiset.isPerfectlyBalanced()).toBe(false);
|
||||
const dfsInorderNodes = treeMultiset.DFS('in', 'node');
|
||||
expect(dfsInorderNodes[0].id).toBe(1);
|
||||
expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
expect(treeMultiset.isPerfectlyBalanced()).toBe(false);
|
||||
|
||||
treeMultiset.perfectlyBalance();
|
||||
treeMultiset.perfectlyBalance();
|
||||
|
||||
expect(treeMultiset.isPerfectlyBalanced()).toBe(true);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.isPerfectlyBalanced()).toBe(true);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced = treeMultiset.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
const bfsNodesAfterBalanced = treeMultiset.BFS('node');
|
||||
expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
|
||||
const removed11 = treeMultiset.remove(11, true);
|
||||
expect(removed11 instanceof Array);
|
||||
expect(removed11[0]);
|
||||
expect(removed11[0].deleted);
|
||||
const removed11 = treeMultiset.remove(11, true);
|
||||
expect(removed11 instanceof Array);
|
||||
expect(removed11[0]);
|
||||
expect(removed11[0].deleted);
|
||||
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(treeMultiset.getHeight(15)).toBe(1);
|
||||
expect(treeMultiset.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = treeMultiset.remove(1, true);
|
||||
expect(removed1 instanceof Array);
|
||||
expect(removed1[0]);
|
||||
expect(removed1[0].deleted);
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
const removed1 = treeMultiset.remove(1, true);
|
||||
expect(removed1 instanceof Array);
|
||||
expect(removed1[0]);
|
||||
expect(removed1[0].deleted);
|
||||
if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(treeMultiset.getHeight()).toBe(4);
|
||||
expect(treeMultiset.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = treeMultiset.remove(4, true);
|
||||
expect(removed4 instanceof Array);
|
||||
expect(removed4[0]);
|
||||
expect(removed4[0].deleted);
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
const removed4 = treeMultiset.remove(4, true);
|
||||
expect(removed4 instanceof Array);
|
||||
expect(removed4[0]);
|
||||
expect(removed4[0].deleted);
|
||||
if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(4);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = treeMultiset.remove(10, true);
|
||||
expect(removed10 instanceof Array);
|
||||
expect(removed10[0]);
|
||||
expect(removed10[0].deleted);
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
const removed10 = treeMultiset.remove(10, true);
|
||||
expect(removed10 instanceof Array);
|
||||
expect(removed10[0]);
|
||||
expect(removed10[0].deleted);
|
||||
if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
|
||||
const removed15 = treeMultiset.remove(15, true);
|
||||
expect(removed15 instanceof Array);
|
||||
expect(removed15[0]);
|
||||
expect(removed15[0].deleted);
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
const removed15 = treeMultiset.remove(15, true);
|
||||
expect(removed15 instanceof Array);
|
||||
expect(removed15[0]);
|
||||
expect(removed15[0].deleted);
|
||||
if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = treeMultiset.remove(5, true);
|
||||
expect(removed5 instanceof Array);
|
||||
expect(removed5[0]);
|
||||
expect(removed5[0].deleted);
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
const removed5 = treeMultiset.remove(5, true);
|
||||
expect(removed5 instanceof Array);
|
||||
expect(removed5[0]);
|
||||
expect(removed5[0].deleted);
|
||||
if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = treeMultiset.remove(13, true);
|
||||
expect(removed13 instanceof Array);
|
||||
expect(removed13[0]);
|
||||
expect(removed13[0].deleted);
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
const removed13 = treeMultiset.remove(13, true);
|
||||
expect(removed13 instanceof Array);
|
||||
expect(removed13[0]);
|
||||
expect(removed13[0].deleted);
|
||||
if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = treeMultiset.remove(3, true);
|
||||
expect(removed3 instanceof Array);
|
||||
expect(removed3[0]);
|
||||
expect(removed3[0].deleted);
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
const removed3 = treeMultiset.remove(3, true);
|
||||
expect(removed3 instanceof Array);
|
||||
expect(removed3[0]);
|
||||
expect(removed3[0].deleted);
|
||||
if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = treeMultiset.remove(8, true);
|
||||
expect(removed8 instanceof Array);
|
||||
expect(removed8[0]);
|
||||
expect(removed8[0].deleted);
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
const removed8 = treeMultiset.remove(8, true);
|
||||
expect(removed8 instanceof Array);
|
||||
expect(removed8[0]);
|
||||
expect(removed8[0].deleted);
|
||||
if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = treeMultiset.remove(6, true);
|
||||
expect(removed6 instanceof Array);
|
||||
expect(removed6[0]);
|
||||
expect(removed6[0].deleted);
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(treeMultiset.remove(6, true).length).toBe(0);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
const removed6 = treeMultiset.remove(6, true);
|
||||
expect(removed6 instanceof Array);
|
||||
expect(removed6[0]);
|
||||
expect(removed6[0].deleted);
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
expect(treeMultiset.remove(6, true).length).toBe(0);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(treeMultiset.getHeight()).toBe(2);
|
||||
expect(treeMultiset.getHeight()).toBe(2);
|
||||
|
||||
const removed7 = treeMultiset.remove(7, true);
|
||||
expect(removed7 instanceof Array);
|
||||
expect(removed7[0]);
|
||||
expect(removed7[0].deleted);
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(2);
|
||||
const removed7 = treeMultiset.remove(7, true);
|
||||
expect(removed7 instanceof Array);
|
||||
expect(removed7[0]);
|
||||
expect(removed7[0].deleted);
|
||||
if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(2);
|
||||
|
||||
const removed9 = treeMultiset.remove(9, true);
|
||||
expect(removed9 instanceof Array);
|
||||
expect(removed9[0]);
|
||||
expect(removed9[0].deleted);
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(2);
|
||||
const removed9 = treeMultiset.remove(9, true);
|
||||
expect(removed9 instanceof Array);
|
||||
expect(removed9[0]);
|
||||
expect(removed9[0].deleted);
|
||||
if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(2);
|
||||
|
||||
const removed14 = treeMultiset.remove(14, true);
|
||||
expect(removed14 instanceof Array);
|
||||
expect(removed14[0]);
|
||||
expect(removed14[0].deleted);
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(1);
|
||||
const removed14 = treeMultiset.remove(14, true);
|
||||
expect(removed14 instanceof Array);
|
||||
expect(removed14[0]);
|
||||
expect(removed14[0].deleted);
|
||||
if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.getHeight()).toBe(1);
|
||||
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultiset.isAVLBalanced()).toBe(true);
|
||||
|
||||
const bfsIDs = treeMultiset.BFS();
|
||||
const bfsIDs = treeMultiset.BFS();
|
||||
|
||||
expect(bfsIDs[0]).toBe(12);
|
||||
expect(bfsIDs[1]).toBe(2);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
expect(bfsIDs[0]).toBe(12);
|
||||
expect(bfsIDs[1]).toBe(2);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes = treeMultiset.BFS('node');
|
||||
const bfsNodes = treeMultiset.BFS('node');
|
||||
|
||||
expect(bfsNodes[0].id).toBe(12);
|
||||
expect(bfsNodes[1].id).toBe(2);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
expect(bfsNodes[0].id).toBe(12);
|
||||
expect(bfsNodes[1].id).toBe(2);
|
||||
expect(bfsNodes[2].id).toBe(16);
|
||||
|
||||
expect(treeMultiset.count).toBe(9);
|
||||
});
|
||||
expect(treeMultiset.count).toBe(9);
|
||||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objTreeMultiset = new TreeMultiset<TreeMultisetNode<{ id: number, keyA: number }>>();
|
||||
expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
|
||||
objTreeMultiset.add(11, {id: 11, keyA: 11});
|
||||
objTreeMultiset.add(3, {id: 3, keyA: 3});
|
||||
const values = [{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
|
||||
{id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2},
|
||||
{id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12},
|
||||
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
|
||||
{id: 10, keyA: 10}, {id: 5, keyA: 5}];
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objTreeMultiset = new TreeMultiset<TreeMultisetNode<{ id: number, keyA: number }>>();
|
||||
expect(objTreeMultiset).toBeInstanceOf(TreeMultiset);
|
||||
objTreeMultiset.add(11, {id: 11, keyA: 11});
|
||||
objTreeMultiset.add(3, {id: 3, keyA: 3});
|
||||
const values = [{id: 15, keyA: 15}, {id: 1, keyA: 1}, {id: 8, keyA: 8},
|
||||
{id: 13, keyA: 13}, {id: 16, keyA: 16}, {id: 2, keyA: 2},
|
||||
{id: 6, keyA: 6}, {id: 9, keyA: 9}, {id: 12, keyA: 12},
|
||||
{id: 14, keyA: 14}, {id: 4, keyA: 4}, {id: 7, keyA: 7},
|
||||
{id: 10, keyA: 10}, {id: 5, keyA: 5}];
|
||||
|
||||
objTreeMultiset.addMany(values.map(item => item.id), values);
|
||||
objTreeMultiset.addMany(values.map(item => item.id), values);
|
||||
|
||||
expect(objTreeMultiset.root).toBeInstanceOf(TreeMultisetNode);
|
||||
expect(objTreeMultiset.root).toBeInstanceOf(TreeMultisetNode);
|
||||
|
||||
if (objTreeMultiset.root) expect(objTreeMultiset.root.id).toBe(11);
|
||||
if (objTreeMultiset.root) expect(objTreeMultiset.root.id).toBe(11);
|
||||
|
||||
expect(objTreeMultiset.count).toBe(16);
|
||||
expect(objTreeMultiset.count).toBe(16);
|
||||
|
||||
expect(objTreeMultiset.has(6)).toBe(true);
|
||||
expect(objTreeMultiset.has(6)).toBe(true);
|
||||
|
||||
const node6 = objTreeMultiset.get(6);
|
||||
// expect(node6 && objTreeMultiset.getHeight(node6)).toBe(2);
|
||||
// expect(node6 && objTreeMultiset.getDepth(node6)).toBe(3);
|
||||
//
|
||||
// const nodeId10 = objTreeMultiset.get(10, 'id');
|
||||
// expect(nodeId10?.id).toBe(10);
|
||||
//
|
||||
// const nodeVal9 = objTreeMultiset.get(9, 'id');
|
||||
// expect(nodeVal9?.id).toBe(9);
|
||||
//
|
||||
// const nodesByCount1 = objTreeMultiset.getNodesByCount(1);
|
||||
// expect(nodesByCount1.length).toBe(16);
|
||||
//
|
||||
// const leftMost = objTreeMultiset.getLeftMost();
|
||||
// expect(leftMost?.id).toBe(1);
|
||||
//
|
||||
// const node15 = objTreeMultiset.get(15);
|
||||
// expect(node15?.val).toEqual({id: 15, keyA: 15});
|
||||
// const minNodeBySpecificNode = node15 && objTreeMultiset.getLeftMost(node15);
|
||||
// expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
//
|
||||
// const subTreeSum = node15 && objTreeMultiset.subTreeSum(node15);
|
||||
// expect(subTreeSum).toBe(70);
|
||||
//
|
||||
// const lesserSum = objTreeMultiset.lesserSum(10);
|
||||
// expect(lesserSum).toBe(45);
|
||||
//
|
||||
// expect(node15).toBeInstanceOf(TreeMultisetNode);
|
||||
// if (node15 instanceof TreeMultisetNode) {
|
||||
// const subTreeAdd = objTreeMultiset.subTreeAddCount(node15, 1);
|
||||
// expect(subTreeAdd).toBeDefined();
|
||||
// }
|
||||
//
|
||||
// const node11 = objTreeMultiset.get(11);
|
||||
// expect(node11).toBeInstanceOf(TreeMultisetNode);
|
||||
// if (node11 instanceof TreeMultisetNode) {
|
||||
// const allGreaterNodesAdded = objTreeMultiset.allGreaterNodesAddCount(node11, 2);
|
||||
// expect(allGreaterNodesAdded).toBeDefined();
|
||||
// }
|
||||
//
|
||||
// const dfsInorderNodes = objTreeMultiset.DFS('in', 'node');
|
||||
// expect(dfsInorderNodes[0].id).toBe(1);
|
||||
// expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
//
|
||||
// objTreeMultiset.perfectlyBalance();
|
||||
// expect(objTreeMultiset.isPerfectlyBalanced()).toBe(true);
|
||||
//
|
||||
// const bfsNodesAfterBalanced = objTreeMultiset.BFS('node');
|
||||
// expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
// expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
//
|
||||
// const removed11 = objTreeMultiset.remove(11, true);
|
||||
// expect(removed11).toBeInstanceOf(Array);
|
||||
// expect(removed11[0]).toBeDefined();
|
||||
// expect(removed11[0].deleted).toBeDefined();
|
||||
//
|
||||
// if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
//
|
||||
// expect(node15 && objTreeMultiset.getHeight(node15)).toBe(2);
|
||||
//
|
||||
// const removed1 = objTreeMultiset.remove(1, true);
|
||||
// expect(removed1).toBeInstanceOf(Array);
|
||||
// expect(removed1[0]).toBeDefined();
|
||||
// expect(removed1[0].deleted).toBeDefined();
|
||||
// if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
//
|
||||
// expect(objTreeMultiset.getHeight()).toBe(4);
|
||||
//
|
||||
// const removed4 = objTreeMultiset.remove(4, true);
|
||||
// expect(removed4).toBeInstanceOf(Array);
|
||||
// expect(removed4[0]).toBeDefined();
|
||||
// expect(removed4[0].deleted).toBeDefined();
|
||||
// if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(4);
|
||||
//
|
||||
// const removed10 = objTreeMultiset.remove(10, true);
|
||||
// expect(removed10).toBeInstanceOf(Array);
|
||||
// expect(removed10[0]).toBeDefined();
|
||||
// expect(removed10[0].deleted).toBeDefined();
|
||||
// if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(4);
|
||||
//
|
||||
// const removed15 = objTreeMultiset.remove(15, true);
|
||||
// expect(removed15).toBeInstanceOf(Array);
|
||||
// expect(removed15[0]).toBeDefined();
|
||||
// expect(removed15[0].deleted).toBeDefined();
|
||||
// if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed5 = objTreeMultiset.remove(5, true);
|
||||
// expect(removed5).toBeInstanceOf(Array);
|
||||
// expect(removed5[0]).toBeDefined();
|
||||
// expect(removed5[0].deleted).toBeDefined();
|
||||
// if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed13 = objTreeMultiset.remove(13, true);
|
||||
// expect(removed13).toBeInstanceOf(Array);
|
||||
// expect(removed13[0]).toBeDefined();
|
||||
// expect(removed13[0].deleted).toBeDefined();
|
||||
// if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed3 = objTreeMultiset.remove(3, true);
|
||||
// expect(removed3).toBeInstanceOf(Array);
|
||||
// expect(removed3[0]).toBeDefined();
|
||||
// expect(removed3[0].deleted).toBeDefined();
|
||||
// if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed8 = objTreeMultiset.remove(8, true);
|
||||
// expect(removed8).toBeInstanceOf(Array);
|
||||
// expect(removed8[0]).toBeDefined();
|
||||
// expect(removed8[0].deleted).toBeDefined();
|
||||
// if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed6 = objTreeMultiset.remove(6, true);
|
||||
// expect(removed6).toBeInstanceOf(Array);
|
||||
// expect(removed6[0]).toBeDefined();
|
||||
// expect(removed6[0].deleted).toBeDefined();
|
||||
// if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
// expect(objTreeMultiset.remove(6, true).length).toBe(0);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed7 = objTreeMultiset.remove(7, true);
|
||||
// expect(removed7).toBeInstanceOf(Array);
|
||||
// expect(removed7[0]).toBeDefined();
|
||||
// expect(removed7[0].deleted).toBeDefined();
|
||||
// if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed9 = objTreeMultiset.remove(9, true);
|
||||
// expect(removed9).toBeInstanceOf(Array);
|
||||
// expect(removed9[0]).toBeDefined();
|
||||
// expect(removed9[0].deleted).toBeDefined();
|
||||
// if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed14 = objTreeMultiset.remove(14, true);
|
||||
// expect(removed14).toBeInstanceOf(Array);
|
||||
// expect(removed14[0]).toBeDefined();
|
||||
// expect(removed14[0].deleted).toBeDefined();
|
||||
// if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(2);
|
||||
//
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
//
|
||||
// const bfsIDs = objTreeMultiset.BFS();
|
||||
// expect(bfsIDs[0]).toBe(2);
|
||||
// expect(bfsIDs[1]).toBe(12);
|
||||
// expect(bfsIDs[2]).toBe(16);
|
||||
//
|
||||
// const bfsNodes = objTreeMultiset.BFS('node');
|
||||
// expect(bfsNodes[0].id).toBe(2);
|
||||
// expect(bfsNodes[1].id).toBe(12);
|
||||
// expect(bfsNodes[2].id).toBe(16);
|
||||
//
|
||||
// expect(objTreeMultiset.count).toBe(5);
|
||||
});
|
||||
const node6 = objTreeMultiset.get(6);
|
||||
// expect(node6 && objTreeMultiset.getHeight(node6)).toBe(2);
|
||||
// expect(node6 && objTreeMultiset.getDepth(node6)).toBe(3);
|
||||
//
|
||||
// const nodeId10 = objTreeMultiset.get(10, 'id');
|
||||
// expect(nodeId10?.id).toBe(10);
|
||||
//
|
||||
// const nodeVal9 = objTreeMultiset.get(9, 'id');
|
||||
// expect(nodeVal9?.id).toBe(9);
|
||||
//
|
||||
// const nodesByCount1 = objTreeMultiset.getNodesByCount(1);
|
||||
// expect(nodesByCount1.length).toBe(16);
|
||||
//
|
||||
// const leftMost = objTreeMultiset.getLeftMost();
|
||||
// expect(leftMost?.id).toBe(1);
|
||||
//
|
||||
// const node15 = objTreeMultiset.get(15);
|
||||
// expect(node15?.val).toEqual({id: 15, keyA: 15});
|
||||
// const minNodeBySpecificNode = node15 && objTreeMultiset.getLeftMost(node15);
|
||||
// expect(minNodeBySpecificNode?.id).toBe(12);
|
||||
//
|
||||
// const subTreeSum = node15 && objTreeMultiset.subTreeSum(node15);
|
||||
// expect(subTreeSum).toBe(70);
|
||||
//
|
||||
// const lesserSum = objTreeMultiset.lesserSum(10);
|
||||
// expect(lesserSum).toBe(45);
|
||||
//
|
||||
// expect(node15).toBeInstanceOf(TreeMultisetNode);
|
||||
// if (node15 instanceof TreeMultisetNode) {
|
||||
// const subTreeAdd = objTreeMultiset.subTreeAddCount(node15, 1);
|
||||
// expect(subTreeAdd).toBeDefined();
|
||||
// }
|
||||
//
|
||||
// const node11 = objTreeMultiset.get(11);
|
||||
// expect(node11).toBeInstanceOf(TreeMultisetNode);
|
||||
// if (node11 instanceof TreeMultisetNode) {
|
||||
// const allGreaterNodesAdded = objTreeMultiset.allGreaterNodesAddCount(node11, 2);
|
||||
// expect(allGreaterNodesAdded).toBeDefined();
|
||||
// }
|
||||
//
|
||||
// const dfsInorderNodes = objTreeMultiset.DFS('in', 'node');
|
||||
// expect(dfsInorderNodes[0].id).toBe(1);
|
||||
// expect(dfsInorderNodes[dfsInorderNodes.length - 1].id).toBe(16);
|
||||
//
|
||||
// objTreeMultiset.perfectlyBalance();
|
||||
// expect(objTreeMultiset.isPerfectlyBalanced()).toBe(true);
|
||||
//
|
||||
// const bfsNodesAfterBalanced = objTreeMultiset.BFS('node');
|
||||
// expect(bfsNodesAfterBalanced[0].id).toBe(8);
|
||||
// expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].id).toBe(16);
|
||||
//
|
||||
// const removed11 = objTreeMultiset.remove(11, true);
|
||||
// expect(removed11).toBeInstanceOf(Array);
|
||||
// expect(removed11[0]).toBeDefined();
|
||||
// expect(removed11[0].deleted).toBeDefined();
|
||||
//
|
||||
// if (removed11[0].deleted) expect(removed11[0].deleted.id).toBe(11);
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
//
|
||||
// expect(node15 && objTreeMultiset.getHeight(node15)).toBe(2);
|
||||
//
|
||||
// const removed1 = objTreeMultiset.remove(1, true);
|
||||
// expect(removed1).toBeInstanceOf(Array);
|
||||
// expect(removed1[0]).toBeDefined();
|
||||
// expect(removed1[0].deleted).toBeDefined();
|
||||
// if (removed1[0].deleted) expect(removed1[0].deleted.id).toBe(1);
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
//
|
||||
// expect(objTreeMultiset.getHeight()).toBe(4);
|
||||
//
|
||||
// const removed4 = objTreeMultiset.remove(4, true);
|
||||
// expect(removed4).toBeInstanceOf(Array);
|
||||
// expect(removed4[0]).toBeDefined();
|
||||
// expect(removed4[0].deleted).toBeDefined();
|
||||
// if (removed4[0].deleted) expect(removed4[0].deleted.id).toBe(4);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(4);
|
||||
//
|
||||
// const removed10 = objTreeMultiset.remove(10, true);
|
||||
// expect(removed10).toBeInstanceOf(Array);
|
||||
// expect(removed10[0]).toBeDefined();
|
||||
// expect(removed10[0].deleted).toBeDefined();
|
||||
// if (removed10[0].deleted) expect(removed10[0].deleted.id).toBe(10);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(4);
|
||||
//
|
||||
// const removed15 = objTreeMultiset.remove(15, true);
|
||||
// expect(removed15).toBeInstanceOf(Array);
|
||||
// expect(removed15[0]).toBeDefined();
|
||||
// expect(removed15[0].deleted).toBeDefined();
|
||||
// if (removed15[0].deleted) expect(removed15[0].deleted.id).toBe(15);
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed5 = objTreeMultiset.remove(5, true);
|
||||
// expect(removed5).toBeInstanceOf(Array);
|
||||
// expect(removed5[0]).toBeDefined();
|
||||
// expect(removed5[0].deleted).toBeDefined();
|
||||
// if (removed5[0].deleted) expect(removed5[0].deleted.id).toBe(5);
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed13 = objTreeMultiset.remove(13, true);
|
||||
// expect(removed13).toBeInstanceOf(Array);
|
||||
// expect(removed13[0]).toBeDefined();
|
||||
// expect(removed13[0].deleted).toBeDefined();
|
||||
// if (removed13[0].deleted) expect(removed13[0].deleted.id).toBe(13);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed3 = objTreeMultiset.remove(3, true);
|
||||
// expect(removed3).toBeInstanceOf(Array);
|
||||
// expect(removed3[0]).toBeDefined();
|
||||
// expect(removed3[0].deleted).toBeDefined();
|
||||
// if (removed3[0].deleted) expect(removed3[0].deleted.id).toBe(3);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed8 = objTreeMultiset.remove(8, true);
|
||||
// expect(removed8).toBeInstanceOf(Array);
|
||||
// expect(removed8[0]).toBeDefined();
|
||||
// expect(removed8[0].deleted).toBeDefined();
|
||||
// if (removed8[0].deleted) expect(removed8[0].deleted.id).toBe(8);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(true);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed6 = objTreeMultiset.remove(6, true);
|
||||
// expect(removed6).toBeInstanceOf(Array);
|
||||
// expect(removed6[0]).toBeDefined();
|
||||
// expect(removed6[0].deleted).toBeDefined();
|
||||
// if (removed6[0].deleted) expect(removed6[0].deleted.id).toBe(6);
|
||||
// expect(objTreeMultiset.remove(6, true).length).toBe(0);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed7 = objTreeMultiset.remove(7, true);
|
||||
// expect(removed7).toBeInstanceOf(Array);
|
||||
// expect(removed7[0]).toBeDefined();
|
||||
// expect(removed7[0].deleted).toBeDefined();
|
||||
// if (removed7[0].deleted) expect(removed7[0].deleted.id).toBe(7);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed9 = objTreeMultiset.remove(9, true);
|
||||
// expect(removed9).toBeInstanceOf(Array);
|
||||
// expect(removed9[0]).toBeDefined();
|
||||
// expect(removed9[0].deleted).toBeDefined();
|
||||
// if (removed9[0].deleted) expect(removed9[0].deleted.id).toBe(9);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(3);
|
||||
//
|
||||
// const removed14 = objTreeMultiset.remove(14, true);
|
||||
// expect(removed14).toBeInstanceOf(Array);
|
||||
// expect(removed14[0]).toBeDefined();
|
||||
// expect(removed14[0].deleted).toBeDefined();
|
||||
// if (removed14[0].deleted) expect(removed14[0].deleted.id).toBe(14);
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
// expect(objTreeMultiset.getHeight()).toBe(2);
|
||||
//
|
||||
//
|
||||
// expect(objTreeMultiset.isAVLBalanced()).toBe(false);
|
||||
//
|
||||
// const bfsIDs = objTreeMultiset.BFS();
|
||||
// expect(bfsIDs[0]).toBe(2);
|
||||
// expect(bfsIDs[1]).toBe(12);
|
||||
// expect(bfsIDs[2]).toBe(16);
|
||||
//
|
||||
// const bfsNodes = objTreeMultiset.BFS('node');
|
||||
// expect(bfsNodes[0].id).toBe(2);
|
||||
// expect(bfsNodes[1].id).toBe(12);
|
||||
// expect(bfsNodes[2].id).toBe(16);
|
||||
//
|
||||
// expect(objTreeMultiset.count).toBe(5);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
export * from './magnitude';
|
|
@ -1,11 +0,0 @@
|
|||
const orderReducedBy = 2; // reduction of magnitude's order compared to the baseline magnitude
|
||||
|
||||
export const magnitude = {
|
||||
CONSTANT: Math.floor(Number.MAX_SAFE_INTEGER / Math.pow(10, orderReducedBy)),
|
||||
LOG_N: Math.pow(10, 9 - orderReducedBy),
|
||||
LINEAR: Math.pow(10, 6 - orderReducedBy),
|
||||
N_LOG_N: Math.pow(10, 5 - orderReducedBy),
|
||||
SQUARED: Math.pow(10, 4 - orderReducedBy),
|
||||
CUBED: Math.pow(10, 3 - orderReducedBy),
|
||||
FACTORIAL: 20 - orderReducedBy
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
describe('AbstractGraph Operation Test', () => {
|
||||
it('should xxx', function () {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
});
|
||||
it('should xxx', function () {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,517 +1,517 @@
|
|||
import {DirectedEdge, DirectedGraph, DirectedVertex, VertexId} from '../../../../src';
|
||||
|
||||
describe('DirectedGraph Operation Test', () => {
|
||||
let graph: DirectedGraph;
|
||||
let graph: DirectedGraph;
|
||||
|
||||
beforeEach(() => {
|
||||
graph = new DirectedGraph();
|
||||
});
|
||||
beforeEach(() => {
|
||||
graph = new DirectedGraph();
|
||||
});
|
||||
|
||||
|
||||
it('should add vertices', () => {
|
||||
const vertex1 = new DirectedVertex('A');
|
||||
const vertex2 = new DirectedVertex('B');
|
||||
it('should add vertices', () => {
|
||||
const vertex1 = new DirectedVertex('A');
|
||||
const vertex2 = new DirectedVertex('B');
|
||||
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
|
||||
expect(graph.hasVertex(vertex1)).toBe(true);
|
||||
expect(graph.hasVertex(vertex2)).toBe(true);
|
||||
});
|
||||
expect(graph.hasVertex(vertex1)).toBe(true);
|
||||
expect(graph.hasVertex(vertex2)).toBe(true);
|
||||
});
|
||||
|
||||
it('should add edges', () => {
|
||||
const vertex1 = new DirectedVertex('A');
|
||||
const vertex2 = new DirectedVertex('B');
|
||||
const edge = new DirectedEdge('A', 'B');
|
||||
it('should add edges', () => {
|
||||
const vertex1 = new DirectedVertex('A');
|
||||
const vertex2 = new DirectedVertex('B');
|
||||
const edge = new DirectedEdge('A', 'B');
|
||||
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addEdge(edge);
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addEdge(edge);
|
||||
|
||||
expect(graph.hasEdge('A', 'B')).toBe(true);
|
||||
expect(graph.hasEdge('B', 'A')).toBe(false);
|
||||
});
|
||||
expect(graph.hasEdge('A', 'B')).toBe(true);
|
||||
expect(graph.hasEdge('B', 'A')).toBe(false);
|
||||
});
|
||||
|
||||
it('should remove edges', () => {
|
||||
const vertex1 = new DirectedVertex('A');
|
||||
const vertex2 = new DirectedVertex('B');
|
||||
const edge = new DirectedEdge('A', 'B');
|
||||
it('should remove edges', () => {
|
||||
const vertex1 = new DirectedVertex('A');
|
||||
const vertex2 = new DirectedVertex('B');
|
||||
const edge = new DirectedEdge('A', 'B');
|
||||
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addEdge(edge);
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addEdge(edge);
|
||||
|
||||
expect(graph.removeEdge(edge)).toBe(edge);
|
||||
expect(graph.hasEdge('A', 'B')).toBe(false);
|
||||
});
|
||||
expect(graph.removeEdge(edge)).toBe(edge);
|
||||
expect(graph.hasEdge('A', 'B')).toBe(false);
|
||||
});
|
||||
|
||||
it('should perform topological sort', () => {
|
||||
const vertexA = new DirectedVertex('A');
|
||||
const vertexB = new DirectedVertex('B');
|
||||
const vertexC = new DirectedVertex('C');
|
||||
const edgeAB = new DirectedEdge('A', 'B');
|
||||
const edgeBC = new DirectedEdge('B', 'C');
|
||||
it('should perform topological sort', () => {
|
||||
const vertexA = new DirectedVertex('A');
|
||||
const vertexB = new DirectedVertex('B');
|
||||
const vertexC = new DirectedVertex('C');
|
||||
const edgeAB = new DirectedEdge('A', 'B');
|
||||
const edgeBC = new DirectedEdge('B', 'C');
|
||||
|
||||
graph.addVertex(vertexA);
|
||||
graph.addVertex(vertexB);
|
||||
graph.addVertex(vertexC);
|
||||
graph.addEdge(edgeAB);
|
||||
graph.addEdge(edgeBC);
|
||||
graph.addVertex(vertexA);
|
||||
graph.addVertex(vertexB);
|
||||
graph.addVertex(vertexC);
|
||||
graph.addEdge(edgeAB);
|
||||
graph.addEdge(edgeBC);
|
||||
|
||||
const topologicalOrder = graph.topologicalSort();
|
||||
if (topologicalOrder) expect(topologicalOrder).toEqual(['A', 'B', 'C']);
|
||||
});
|
||||
const topologicalOrder = graph.topologicalSort();
|
||||
if (topologicalOrder) expect(topologicalOrder).toEqual(['A', 'B', 'C']);
|
||||
});
|
||||
});
|
||||
|
||||
class MyVertex<V extends string> extends DirectedVertex<V> {
|
||||
|
||||
constructor(id: VertexId, val?: V) {
|
||||
super(id, val);
|
||||
this._data = val;
|
||||
}
|
||||
constructor(id: VertexId, val?: V) {
|
||||
super(id, val);
|
||||
this._data = val;
|
||||
}
|
||||
|
||||
private _data: string | undefined;
|
||||
private _data: string | undefined;
|
||||
|
||||
get data(): string | undefined {
|
||||
return this._data;
|
||||
}
|
||||
get data(): string | undefined {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
set data(value: string | undefined) {
|
||||
this._data = value;
|
||||
}
|
||||
set data(value: string | undefined) {
|
||||
this._data = value;
|
||||
}
|
||||
}
|
||||
|
||||
class MyEdge<E extends string> extends DirectedEdge<E> {
|
||||
|
||||
constructor(v1: VertexId, v2: VertexId, weight?: number, val?: E) {
|
||||
super(v1, v2, weight, val);
|
||||
this._data = val;
|
||||
}
|
||||
constructor(v1: VertexId, v2: VertexId, weight?: number, val?: E) {
|
||||
super(v1, v2, weight, val);
|
||||
this._data = val;
|
||||
}
|
||||
|
||||
private _data: string | undefined;
|
||||
private _data: string | undefined;
|
||||
|
||||
get data(): string | undefined {
|
||||
return this._data;
|
||||
}
|
||||
get data(): string | undefined {
|
||||
return this._data;
|
||||
}
|
||||
|
||||
set data(value: string | undefined) {
|
||||
this._data = value;
|
||||
}
|
||||
set data(value: string | undefined) {
|
||||
this._data = value;
|
||||
}
|
||||
}
|
||||
|
||||
class MyDirectedGraph<V extends MyVertex<string>, E extends MyEdge<string>> extends DirectedGraph<V, E> {
|
||||
createVertex(id: VertexId, val: V['val']): V {
|
||||
return new MyVertex(id, val) as V;
|
||||
}
|
||||
createVertex(id: VertexId, val: V['val']): V {
|
||||
return new MyVertex(id, val) as V;
|
||||
}
|
||||
|
||||
createEdge(src: VertexId, dest: VertexId, weight?: number, val?: E['val']): E {
|
||||
return new MyEdge(src, dest, weight ?? 1, val) as E;
|
||||
}
|
||||
createEdge(src: VertexId, dest: VertexId, weight?: number, val?: E['val']): E {
|
||||
return new MyEdge(src, dest, weight ?? 1, val) as E;
|
||||
}
|
||||
}
|
||||
|
||||
describe('Inherit from DirectedGraph and perform operations', () => {
|
||||
let myGraph = new MyDirectedGraph<MyVertex<string>, MyEdge<string>>();
|
||||
beforeEach(() => {
|
||||
myGraph = new MyDirectedGraph();
|
||||
});
|
||||
let myGraph = new MyDirectedGraph<MyVertex<string>, MyEdge<string>>();
|
||||
beforeEach(() => {
|
||||
myGraph = new MyDirectedGraph();
|
||||
});
|
||||
|
||||
it('Add vertices', () => {
|
||||
myGraph.addVertex(1, 'data1');
|
||||
myGraph.addVertex(2, 'data2');
|
||||
myGraph.addVertex(3, 'data3');
|
||||
myGraph.addVertex(4, 'data4');
|
||||
myGraph.addVertex(5, 'data5');
|
||||
myGraph.addVertex(new MyVertex(6, 'data6'));
|
||||
myGraph.addVertex(new MyVertex(7, 'data7'));
|
||||
myGraph.addVertex(new MyVertex(8, 'data8'));
|
||||
myGraph.addVertex(new MyVertex(9, 'data9'));
|
||||
it('Add vertices', () => {
|
||||
myGraph.addVertex(1, 'data1');
|
||||
myGraph.addVertex(2, 'data2');
|
||||
myGraph.addVertex(3, 'data3');
|
||||
myGraph.addVertex(4, 'data4');
|
||||
myGraph.addVertex(5, 'data5');
|
||||
myGraph.addVertex(new MyVertex(6, 'data6'));
|
||||
myGraph.addVertex(new MyVertex(7, 'data7'));
|
||||
myGraph.addVertex(new MyVertex(8, 'data8'));
|
||||
myGraph.addVertex(new MyVertex(9, 'data9'));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('Add edges', () => {
|
||||
myGraph.addVertex(1, 'data1');
|
||||
myGraph.addVertex(2, 'data2');
|
||||
myGraph.addEdge(1, 2, 10, 'edge-data1-2');
|
||||
myGraph.addEdge(new MyEdge(2, 1, 20, 'edge-data2-1'));
|
||||
it('Add edges', () => {
|
||||
myGraph.addVertex(1, 'data1');
|
||||
myGraph.addVertex(2, 'data2');
|
||||
myGraph.addEdge(1, 2, 10, 'edge-data1-2');
|
||||
myGraph.addEdge(new MyEdge(2, 1, 20, 'edge-data2-1'));
|
||||
|
||||
expect(myGraph.edgeSet().length).toBe(2);
|
||||
// TODO
|
||||
expect(myGraph.getEdge(1, 2)).toBeInstanceOf(MyEdge);
|
||||
expect(myGraph.getEdge(2, 1)).toBeInstanceOf(MyEdge);
|
||||
});
|
||||
expect(myGraph.edgeSet().length).toBe(2);
|
||||
// TODO
|
||||
expect(myGraph.getEdge(1, 2)).toBeInstanceOf(MyEdge);
|
||||
expect(myGraph.getEdge(2, 1)).toBeInstanceOf(MyEdge);
|
||||
});
|
||||
|
||||
it('Get edge', () => {
|
||||
myGraph.addVertex(1, 'val1');
|
||||
myGraph.addVertex(2, 'val1');
|
||||
myGraph.addEdge(1, 2, 1, 'val1');
|
||||
const edge1 = myGraph.getEdge(1, 2);
|
||||
const edge2 = myGraph.getEdge(myGraph.getVertex(1), myGraph.getVertex(2));
|
||||
const edge3 = myGraph.getEdge(1, '100');
|
||||
// edge1.data has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
||||
expect(edge1).toBeInstanceOf(MyEdge);
|
||||
if (edge1) {
|
||||
expect(edge1.data).toBe('val1');
|
||||
expect(edge1?.val).toBe('val1');
|
||||
expect(edge1).toBeInstanceOf(MyEdge);
|
||||
expect(edge1.src).toBe(1);
|
||||
expect(edge1).toEqual(edge2);
|
||||
expect(edge3).toBeNull();
|
||||
}
|
||||
it('Get edge', () => {
|
||||
myGraph.addVertex(1, 'val1');
|
||||
myGraph.addVertex(2, 'val1');
|
||||
myGraph.addEdge(1, 2, 1, 'val1');
|
||||
const edge1 = myGraph.getEdge(1, 2);
|
||||
const edge2 = myGraph.getEdge(myGraph.getVertex(1), myGraph.getVertex(2));
|
||||
const edge3 = myGraph.getEdge(1, '100');
|
||||
// edge1.data has type problem. After the uniform design, the generics of containers (DirectedGraph, BST) are based on the type of value. However, this design has a drawback: when I attempt to inherit from the Vertex or BSTNode classes, the types of the results obtained by all methods are those of the parent class.
|
||||
expect(edge1).toBeInstanceOf(MyEdge);
|
||||
if (edge1) {
|
||||
expect(edge1.data).toBe('val1');
|
||||
expect(edge1?.val).toBe('val1');
|
||||
expect(edge1).toBeInstanceOf(MyEdge);
|
||||
expect(edge1.src).toBe(1);
|
||||
expect(edge1).toEqual(edge2);
|
||||
expect(edge3).toBeNull();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('Edge set and vertex set', () => {
|
||||
const edges = myGraph.edgeSet();
|
||||
const vertices = myGraph.vertices;
|
||||
it('Edge set and vertex set', () => {
|
||||
const edges = myGraph.edgeSet();
|
||||
const vertices = myGraph.vertices;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('Remove edge between vertices', () => {
|
||||
myGraph.addVertex(1, 'data1');
|
||||
myGraph.addVertex(2, 'data2');
|
||||
myGraph.addEdge(1, 2, 10, 'edge-data1-2');
|
||||
it('Remove edge between vertices', () => {
|
||||
myGraph.addVertex(1, 'data1');
|
||||
myGraph.addVertex(2, 'data2');
|
||||
myGraph.addEdge(1, 2, 10, 'edge-data1-2');
|
||||
|
||||
const removedEdge = myGraph.removeEdgeSrcToDest(1, 2);
|
||||
const edgeAfterRemoval = myGraph.getEdge(1, 2);
|
||||
const removedEdge = myGraph.removeEdgeSrcToDest(1, 2);
|
||||
const edgeAfterRemoval = myGraph.getEdge(1, 2);
|
||||
|
||||
expect(removedEdge).toBeInstanceOf(MyEdge);
|
||||
if (removedEdge) {
|
||||
removedEdge && expect(removedEdge.val).toBe('edge-data1-2');
|
||||
removedEdge && expect(removedEdge.src).toBe(1)
|
||||
}
|
||||
expect(edgeAfterRemoval).toBeNull();
|
||||
});
|
||||
expect(removedEdge).toBeInstanceOf(MyEdge);
|
||||
if (removedEdge) {
|
||||
removedEdge && expect(removedEdge.val).toBe('edge-data1-2');
|
||||
removedEdge && expect(removedEdge.src).toBe(1)
|
||||
}
|
||||
expect(edgeAfterRemoval).toBeNull();
|
||||
});
|
||||
|
||||
it('Topological sort', () => {
|
||||
it('Topological sort', () => {
|
||||
|
||||
const sorted = myGraph.topologicalSort();
|
||||
const sorted = myGraph.topologicalSort();
|
||||
|
||||
expect(sorted).toBeInstanceOf(Array);
|
||||
if (sorted && sorted.length > 0) {
|
||||
expect(sorted.length).toBe(9);
|
||||
if (sorted[0] instanceof MyVertex) expect(sorted[0].data).toBe('data9');
|
||||
sorted[3] instanceof MyVertex && expect(sorted[3].data).toBe('data6');
|
||||
sorted[8] instanceof MyVertex && expect(sorted[8].id).toBe(1);
|
||||
}
|
||||
expect(sorted).toBeInstanceOf(Array);
|
||||
if (sorted && sorted.length > 0) {
|
||||
expect(sorted.length).toBe(9);
|
||||
if (sorted[0] instanceof MyVertex) expect(sorted[0].data).toBe('data9');
|
||||
sorted[3] instanceof MyVertex && expect(sorted[3].data).toBe('data6');
|
||||
sorted[8] instanceof MyVertex && expect(sorted[8].id).toBe(1);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
it('Minimum path between vertices', () => {
|
||||
myGraph.addVertex(new MyVertex(1, 'data1'));
|
||||
myGraph.addVertex(new MyVertex(2, 'data2'));
|
||||
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
||||
it('Minimum path between vertices', () => {
|
||||
myGraph.addVertex(new MyVertex(1, 'data1'));
|
||||
myGraph.addVertex(new MyVertex(2, 'data2'));
|
||||
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
||||
|
||||
const minPath = myGraph.getMinPathBetween(1, 2);
|
||||
});
|
||||
const minPath = myGraph.getMinPathBetween(1, 2);
|
||||
});
|
||||
|
||||
it('All paths between vertices', () => {
|
||||
// Add vertices and edges as needed for this test
|
||||
myGraph.addVertex(new MyVertex(1, 'data1'));
|
||||
myGraph.addVertex(new MyVertex(2, 'data2'));
|
||||
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
||||
it('All paths between vertices', () => {
|
||||
// Add vertices and edges as needed for this test
|
||||
myGraph.addVertex(new MyVertex(1, 'data1'));
|
||||
myGraph.addVertex(new MyVertex(2, 'data2'));
|
||||
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
||||
|
||||
const allPaths = myGraph.getAllPathsBetween(1, 2);
|
||||
const allPaths = myGraph.getAllPathsBetween(1, 2);
|
||||
|
||||
// Add expect statements here to verify the allPaths
|
||||
});
|
||||
// Add expect statements here to verify the allPaths
|
||||
});
|
||||
});
|
||||
|
||||
describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
||||
const myGraph = new MyDirectedGraph<MyVertex<string>, MyEdge<string>>();
|
||||
const myGraph = new MyDirectedGraph<MyVertex<string>, MyEdge<string>>();
|
||||
|
||||
it('should test graph operations', () => {
|
||||
const vertex1 = new MyVertex(1, 'data1');
|
||||
const vertex2 = new MyVertex(2, 'data2');
|
||||
const vertex3 = new MyVertex(3, 'data3');
|
||||
const vertex4 = new MyVertex(4, 'data4');
|
||||
const vertex5 = new MyVertex(5, 'data5');
|
||||
const vertex6 = new MyVertex(6, 'data6');
|
||||
const vertex7 = new MyVertex(7, 'data7');
|
||||
const vertex8 = new MyVertex(8, 'data8');
|
||||
const vertex9 = new MyVertex(9, 'data9');
|
||||
myGraph.addVertex(vertex1);
|
||||
myGraph.addVertex(vertex2);
|
||||
myGraph.addVertex(vertex3);
|
||||
myGraph.addVertex(vertex4);
|
||||
myGraph.addVertex(vertex5);
|
||||
myGraph.addVertex(vertex6);
|
||||
myGraph.addVertex(vertex7);
|
||||
myGraph.addVertex(vertex8);
|
||||
myGraph.addVertex(vertex9);
|
||||
it('should test graph operations', () => {
|
||||
const vertex1 = new MyVertex(1, 'data1');
|
||||
const vertex2 = new MyVertex(2, 'data2');
|
||||
const vertex3 = new MyVertex(3, 'data3');
|
||||
const vertex4 = new MyVertex(4, 'data4');
|
||||
const vertex5 = new MyVertex(5, 'data5');
|
||||
const vertex6 = new MyVertex(6, 'data6');
|
||||
const vertex7 = new MyVertex(7, 'data7');
|
||||
const vertex8 = new MyVertex(8, 'data8');
|
||||
const vertex9 = new MyVertex(9, 'data9');
|
||||
myGraph.addVertex(vertex1);
|
||||
myGraph.addVertex(vertex2);
|
||||
myGraph.addVertex(vertex3);
|
||||
myGraph.addVertex(vertex4);
|
||||
myGraph.addVertex(vertex5);
|
||||
myGraph.addVertex(vertex6);
|
||||
myGraph.addVertex(vertex7);
|
||||
myGraph.addVertex(vertex8);
|
||||
myGraph.addVertex(vertex9);
|
||||
|
||||
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
||||
myGraph.addEdge(new MyEdge(2, 1, 20, 'edge-data2-1'));
|
||||
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
||||
myGraph.addEdge(new MyEdge(2, 1, 20, 'edge-data2-1'));
|
||||
|
||||
expect(myGraph.getEdge(1, 2)).toBeTruthy();
|
||||
expect(myGraph.getEdge(2, 1)).toBeTruthy();
|
||||
expect(myGraph.getEdge(1, '100')).toBeFalsy();
|
||||
expect(myGraph.getEdge(1, 2)).toBeTruthy();
|
||||
expect(myGraph.getEdge(2, 1)).toBeTruthy();
|
||||
expect(myGraph.getEdge(1, '100')).toBeFalsy();
|
||||
|
||||
myGraph.removeEdgeSrcToDest(1, 2);
|
||||
expect(myGraph.getEdge(1, 2)).toBeFalsy();
|
||||
myGraph.removeEdgeSrcToDest(1, 2);
|
||||
expect(myGraph.getEdge(1, 2)).toBeFalsy();
|
||||
|
||||
myGraph.addEdge(3, 1, 3, 'edge-data-3-1');
|
||||
myGraph.addEdge(3, 1, 3, 'edge-data-3-1');
|
||||
|
||||
myGraph.addEdge(1, 9, 19, 'edge-data1-9');
|
||||
myGraph.addEdge(1, 9, 19, 'edge-data1-9');
|
||||
|
||||
myGraph.addEdge(9, 7, 97, 'edge-data9-7');
|
||||
myGraph.addEdge(9, 7, 97, 'edge-data9-7');
|
||||
|
||||
myGraph.addEdge(7, 9, 79, 'edge-data7-9');
|
||||
myGraph.addEdge(7, 9, 79, 'edge-data7-9');
|
||||
|
||||
myGraph.addEdge(1, 4, 14, 'edge-data1-4');
|
||||
myGraph.addEdge(1, 4, 14, 'edge-data1-4');
|
||||
|
||||
myGraph.addEdge(4, 7, 47, 'edge-data4-7');
|
||||
myGraph.addEdge(4, 7, 47, 'edge-data4-7');
|
||||
|
||||
myGraph.addEdge(1, 2, 12, 'edge-data1-2');
|
||||
myGraph.addEdge(1, 2, 12, 'edge-data1-2');
|
||||
|
||||
myGraph.addEdge(2, 3, 23, 'edge-data2-3');
|
||||
myGraph.addEdge(2, 3, 23, 'edge-data2-3');
|
||||
|
||||
myGraph.addEdge(3, 5, 35, 'edge-data3-5');
|
||||
myGraph.addEdge(3, 5, 35, 'edge-data3-5');
|
||||
|
||||
myGraph.addEdge(5, 7, 57, 'edge-data5-7');
|
||||
myGraph.addEdge(5, 7, 57, 'edge-data5-7');
|
||||
|
||||
myGraph.addEdge(new MyEdge(7, 3, 73, 'edge-data7-3'));
|
||||
const topologicalSorted = myGraph.topologicalSort();
|
||||
expect(topologicalSorted).toBeNull();
|
||||
myGraph.addEdge(new MyEdge(7, 3, 73, 'edge-data7-3'));
|
||||
const topologicalSorted = myGraph.topologicalSort();
|
||||
expect(topologicalSorted).toBeNull();
|
||||
|
||||
const minPath1to7 = myGraph.getMinPathBetween(1, 7);
|
||||
const minPath1to7 = myGraph.getMinPathBetween(1, 7);
|
||||
|
||||
expect(minPath1to7).toBeInstanceOf(Array);
|
||||
if (minPath1to7 && minPath1to7.length > 0) {
|
||||
expect(minPath1to7).toHaveLength(3);
|
||||
expect(minPath1to7[0]).toBeInstanceOf(MyVertex);
|
||||
expect(minPath1to7[0].id).toBe(1);
|
||||
expect(minPath1to7[1].id).toBe(9);
|
||||
expect(minPath1to7[2].id).toBe(7);
|
||||
}
|
||||
expect(minPath1to7).toBeInstanceOf(Array);
|
||||
if (minPath1to7 && minPath1to7.length > 0) {
|
||||
expect(minPath1to7).toHaveLength(3);
|
||||
expect(minPath1to7[0]).toBeInstanceOf(MyVertex);
|
||||
expect(minPath1to7[0].id).toBe(1);
|
||||
expect(minPath1to7[1].id).toBe(9);
|
||||
expect(minPath1to7[2].id).toBe(7);
|
||||
}
|
||||
|
||||
const fordResult1 = myGraph.bellmanFord(1);
|
||||
expect(fordResult1).toBeTruthy();
|
||||
expect(fordResult1.hasNegativeCycle).toBeUndefined();
|
||||
const {distMap, preMap, paths, min, minPath} = fordResult1;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
expect(distMap.get(vertex2)).toBe(12);
|
||||
expect(distMap.get(vertex3)).toBe(35);
|
||||
expect(distMap.get(vertex4)).toBe(14);
|
||||
expect(distMap.get(vertex5)).toBe(70);
|
||||
expect(distMap.get(vertex6)).toBe(Infinity);
|
||||
expect(distMap.get(vertex7)).toBe(61);
|
||||
expect(distMap.get(vertex8)).toBe(Infinity);
|
||||
expect(distMap.get(vertex9)).toBe(19);
|
||||
const fordResult1 = myGraph.bellmanFord(1);
|
||||
expect(fordResult1).toBeTruthy();
|
||||
expect(fordResult1.hasNegativeCycle).toBeUndefined();
|
||||
const {distMap, preMap, paths, min, minPath} = fordResult1;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
expect(distMap.get(vertex2)).toBe(12);
|
||||
expect(distMap.get(vertex3)).toBe(35);
|
||||
expect(distMap.get(vertex4)).toBe(14);
|
||||
expect(distMap.get(vertex5)).toBe(70);
|
||||
expect(distMap.get(vertex6)).toBe(Infinity);
|
||||
expect(distMap.get(vertex7)).toBe(61);
|
||||
expect(distMap.get(vertex8)).toBe(Infinity);
|
||||
expect(distMap.get(vertex9)).toBe(19);
|
||||
|
||||
expect(preMap).toBeInstanceOf(Map);
|
||||
expect(preMap.size).toBe(0);
|
||||
expect(preMap).toBeInstanceOf(Map);
|
||||
expect(preMap.size).toBe(0);
|
||||
|
||||
expect(paths).toBeInstanceOf(Array);
|
||||
expect(paths.length).toBe(0);
|
||||
expect(min).toBe(Infinity);
|
||||
expect(minPath).toBeInstanceOf(Array);
|
||||
expect(paths).toBeInstanceOf(Array);
|
||||
expect(paths.length).toBe(0);
|
||||
expect(min).toBe(Infinity);
|
||||
expect(minPath).toBeInstanceOf(Array);
|
||||
|
||||
|
||||
const floydResult = myGraph.floyd();
|
||||
expect(floydResult).toBeTruthy();
|
||||
if (floydResult) {
|
||||
const {costs, predecessor} = floydResult;
|
||||
expect(costs).toBeInstanceOf(Array);
|
||||
expect(costs.length).toBe(9);
|
||||
expect(costs[0]).toEqual([32, 12, 35, 14, 70, Infinity, 61, Infinity, 19]);
|
||||
expect(costs[1]).toEqual([20, 32, 23, 34, 58, Infinity, 81, Infinity, 39]);
|
||||
expect(costs[2]).toEqual([3, 15, 38, 17, 35, Infinity, 64, Infinity, 22]);
|
||||
expect(costs[3]).toEqual([123, 135, 120, 137, 155, Infinity, 47, Infinity, 126]);
|
||||
expect(costs[4]).toEqual([133, 145, 130, 147, 165, Infinity, 57, Infinity, 136]);
|
||||
expect(costs[5]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
||||
expect(costs[6]).toEqual([76, 88, 73, 90, 108, Infinity, 137, Infinity, 79]);
|
||||
expect(costs[7]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
||||
expect(costs[8]).toEqual([173, 185, 170, 187, 205, Infinity, 97, Infinity, 176]);
|
||||
const floydResult = myGraph.floyd();
|
||||
expect(floydResult).toBeTruthy();
|
||||
if (floydResult) {
|
||||
const {costs, predecessor} = floydResult;
|
||||
expect(costs).toBeInstanceOf(Array);
|
||||
expect(costs.length).toBe(9);
|
||||
expect(costs[0]).toEqual([32, 12, 35, 14, 70, Infinity, 61, Infinity, 19]);
|
||||
expect(costs[1]).toEqual([20, 32, 23, 34, 58, Infinity, 81, Infinity, 39]);
|
||||
expect(costs[2]).toEqual([3, 15, 38, 17, 35, Infinity, 64, Infinity, 22]);
|
||||
expect(costs[3]).toEqual([123, 135, 120, 137, 155, Infinity, 47, Infinity, 126]);
|
||||
expect(costs[4]).toEqual([133, 145, 130, 147, 165, Infinity, 57, Infinity, 136]);
|
||||
expect(costs[5]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
||||
expect(costs[6]).toEqual([76, 88, 73, 90, 108, Infinity, 137, Infinity, 79]);
|
||||
expect(costs[7]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
||||
expect(costs[8]).toEqual([173, 185, 170, 187, 205, Infinity, 97, Infinity, 176]);
|
||||
|
||||
expect(predecessor).toBeInstanceOf(Array);
|
||||
expect(predecessor.length).toBe(9);
|
||||
expect(predecessor[0]).toEqual([vertex2, null, vertex2, null, vertex3, null, vertex4, null, null]);
|
||||
expect(predecessor[1]).toEqual([null, vertex1, null, vertex1, vertex3, null, vertex4, null, vertex1]);
|
||||
expect(predecessor[5]).toEqual([null, null, null, null, null, null, null, null, null]);
|
||||
expect(predecessor[7]).toEqual([null, null, null, null, null, null, null, null, null]);
|
||||
expect(predecessor[8]).toEqual([vertex7, vertex7, vertex7, vertex7, vertex7, null, null, null, vertex7]);
|
||||
}
|
||||
expect(predecessor).toBeInstanceOf(Array);
|
||||
expect(predecessor.length).toBe(9);
|
||||
expect(predecessor[0]).toEqual([vertex2, null, vertex2, null, vertex3, null, vertex4, null, null]);
|
||||
expect(predecessor[1]).toEqual([null, vertex1, null, vertex1, vertex3, null, vertex4, null, vertex1]);
|
||||
expect(predecessor[5]).toEqual([null, null, null, null, null, null, null, null, null]);
|
||||
expect(predecessor[7]).toEqual([null, null, null, null, null, null, null, null, null]);
|
||||
expect(predecessor[8]).toEqual([vertex7, vertex7, vertex7, vertex7, vertex7, null, null, null, vertex7]);
|
||||
}
|
||||
|
||||
const dijkstraRes12tt = myGraph.dijkstra(1, 2, true, true);
|
||||
const dijkstraRes12tt = myGraph.dijkstra(1, 2, true, true);
|
||||
|
||||
expect(dijkstraRes12tt).toBeTruthy();
|
||||
if (dijkstraRes12tt) {
|
||||
const {distMap, minDist, minPath, paths, preMap, seen} = dijkstraRes12tt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
expect(distMap.get(vertex2)).toBe(12);
|
||||
expect(distMap.get(vertex3)).toBe(Infinity);
|
||||
expect(distMap.get(vertex4)).toBe(14);
|
||||
expect(distMap.get(vertex5)).toBe(Infinity);
|
||||
expect(distMap.get(vertex6)).toBe(Infinity);
|
||||
expect(distMap.get(vertex7)).toBe(Infinity);
|
||||
expect(distMap.get(vertex8)).toBe(Infinity);
|
||||
expect(distMap.get(vertex9)).toBe(19);
|
||||
expect(dijkstraRes12tt).toBeTruthy();
|
||||
if (dijkstraRes12tt) {
|
||||
const {distMap, minDist, minPath, paths, preMap, seen} = dijkstraRes12tt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
expect(distMap.get(vertex2)).toBe(12);
|
||||
expect(distMap.get(vertex3)).toBe(Infinity);
|
||||
expect(distMap.get(vertex4)).toBe(14);
|
||||
expect(distMap.get(vertex5)).toBe(Infinity);
|
||||
expect(distMap.get(vertex6)).toBe(Infinity);
|
||||
expect(distMap.get(vertex7)).toBe(Infinity);
|
||||
expect(distMap.get(vertex8)).toBe(Infinity);
|
||||
expect(distMap.get(vertex9)).toBe(19);
|
||||
|
||||
expect(minDist).toBe(12);
|
||||
expect(minPath).toBeInstanceOf(Array);
|
||||
expect(minPath.length).toBe(2);
|
||||
expect(minPath[0]).toBe(vertex1);
|
||||
expect(minPath[1]).toBe(vertex2);
|
||||
expect(minDist).toBe(12);
|
||||
expect(minPath).toBeInstanceOf(Array);
|
||||
expect(minPath.length).toBe(2);
|
||||
expect(minPath[0]).toBe(vertex1);
|
||||
expect(minPath[1]).toBe(vertex2);
|
||||
|
||||
expect(paths).toBeInstanceOf(Array);
|
||||
expect(paths.length).toBe(9);
|
||||
expect(paths[0]).toBeInstanceOf(Array);
|
||||
expect(paths[0][0]).toBe(vertex1);
|
||||
expect(paths).toBeInstanceOf(Array);
|
||||
expect(paths.length).toBe(9);
|
||||
expect(paths[0]).toBeInstanceOf(Array);
|
||||
expect(paths[0][0]).toBe(vertex1);
|
||||
|
||||
expect(paths[1]).toBeInstanceOf(Array);
|
||||
expect(paths[1][0]).toBe(vertex1);
|
||||
expect(paths[1][1]).toBe(vertex2);
|
||||
expect(paths[1]).toBeInstanceOf(Array);
|
||||
expect(paths[1][0]).toBe(vertex1);
|
||||
expect(paths[1][1]).toBe(vertex2);
|
||||
|
||||
expect(paths[2]).toBeInstanceOf(Array);
|
||||
expect(paths[2][0]).toBe(vertex3);
|
||||
expect(paths[3]).toBeInstanceOf(Array);
|
||||
expect(paths[3][0]).toBe(vertex1);
|
||||
expect(paths[3][1]).toBe(vertex4);
|
||||
expect(paths[4]).toBeInstanceOf(Array);
|
||||
expect(paths[4][0]).toBe(vertex5);
|
||||
expect(paths[2]).toBeInstanceOf(Array);
|
||||
expect(paths[2][0]).toBe(vertex3);
|
||||
expect(paths[3]).toBeInstanceOf(Array);
|
||||
expect(paths[3][0]).toBe(vertex1);
|
||||
expect(paths[3][1]).toBe(vertex4);
|
||||
expect(paths[4]).toBeInstanceOf(Array);
|
||||
expect(paths[4][0]).toBe(vertex5);
|
||||
|
||||
expect(paths[5]).toBeInstanceOf(Array);
|
||||
expect(paths[5][0]).toBe(vertex6);
|
||||
expect(paths[6]).toBeInstanceOf(Array);
|
||||
expect(paths[6][0]).toBe(vertex7);
|
||||
expect(paths[7]).toBeInstanceOf(Array);
|
||||
expect(paths[7][0]).toBe(vertex8);
|
||||
expect(paths[8]).toBeInstanceOf(Array);
|
||||
expect(paths[8][0]).toBe(vertex1);
|
||||
expect(paths[8][1]).toBe(vertex9);
|
||||
expect(paths[5]).toBeInstanceOf(Array);
|
||||
expect(paths[5][0]).toBe(vertex6);
|
||||
expect(paths[6]).toBeInstanceOf(Array);
|
||||
expect(paths[6][0]).toBe(vertex7);
|
||||
expect(paths[7]).toBeInstanceOf(Array);
|
||||
expect(paths[7][0]).toBe(vertex8);
|
||||
expect(paths[8]).toBeInstanceOf(Array);
|
||||
expect(paths[8][0]).toBe(vertex1);
|
||||
expect(paths[8][1]).toBe(vertex9);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const dijkstraRes1ntt = myGraph.dijkstra(1, null, true, true);
|
||||
const dijkstraRes1ntt = myGraph.dijkstra(1, null, true, true);
|
||||
|
||||
expect(dijkstraRes1ntt).toBeTruthy();
|
||||
if (dijkstraRes1ntt) {
|
||||
const {distMap, minDist, minPath, paths, preMap, seen} = dijkstraRes1ntt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
expect(distMap.get(vertex2)).toBe(12);
|
||||
expect(distMap.get(vertex3)).toBe(35);
|
||||
expect(distMap.get(vertex4)).toBe(14);
|
||||
expect(distMap.get(vertex5)).toBe(70);
|
||||
expect(distMap.get(vertex6)).toBe(Infinity);
|
||||
expect(distMap.get(vertex7)).toBe(61);
|
||||
expect(distMap.get(vertex8)).toBe(Infinity);
|
||||
expect(distMap.get(vertex9)).toBe(19);
|
||||
expect(dijkstraRes1ntt).toBeTruthy();
|
||||
if (dijkstraRes1ntt) {
|
||||
const {distMap, minDist, minPath, paths, preMap, seen} = dijkstraRes1ntt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
expect(distMap.get(vertex2)).toBe(12);
|
||||
expect(distMap.get(vertex3)).toBe(35);
|
||||
expect(distMap.get(vertex4)).toBe(14);
|
||||
expect(distMap.get(vertex5)).toBe(70);
|
||||
expect(distMap.get(vertex6)).toBe(Infinity);
|
||||
expect(distMap.get(vertex7)).toBe(61);
|
||||
expect(distMap.get(vertex8)).toBe(Infinity);
|
||||
expect(distMap.get(vertex9)).toBe(19);
|
||||
|
||||
expect(minDist).toBe(12);
|
||||
expect(minPath).toBeInstanceOf(Array);
|
||||
expect(minPath.length).toBe(2);
|
||||
expect(minPath[0]).toBe(vertex1);
|
||||
expect(minPath[1]).toBe(vertex2);
|
||||
expect(minDist).toBe(12);
|
||||
expect(minPath).toBeInstanceOf(Array);
|
||||
expect(minPath.length).toBe(2);
|
||||
expect(minPath[0]).toBe(vertex1);
|
||||
expect(minPath[1]).toBe(vertex2);
|
||||
|
||||
expect(paths).toBeInstanceOf(Array);
|
||||
expect(paths.length).toBe(9);
|
||||
expect(paths[0]).toBeInstanceOf(Array);
|
||||
expect(paths[0][0]).toBe(vertex1);
|
||||
expect(paths).toBeInstanceOf(Array);
|
||||
expect(paths.length).toBe(9);
|
||||
expect(paths[0]).toBeInstanceOf(Array);
|
||||
expect(paths[0][0]).toBe(vertex1);
|
||||
|
||||
expect(paths[1]).toBeInstanceOf(Array);
|
||||
expect(paths[1][0]).toBe(vertex1);
|
||||
expect(paths[1][1]).toBe(vertex2);
|
||||
expect(paths[1]).toBeInstanceOf(Array);
|
||||
expect(paths[1][0]).toBe(vertex1);
|
||||
expect(paths[1][1]).toBe(vertex2);
|
||||
|
||||
expect(paths[2]).toBeInstanceOf(Array);
|
||||
expect(paths[2][0]).toBe(vertex1);
|
||||
expect(paths[2][1]).toBe(vertex2);
|
||||
expect(paths[2][2]).toBe(vertex3);
|
||||
expect(paths[2]).toBeInstanceOf(Array);
|
||||
expect(paths[2][0]).toBe(vertex1);
|
||||
expect(paths[2][1]).toBe(vertex2);
|
||||
expect(paths[2][2]).toBe(vertex3);
|
||||
|
||||
expect(paths[3]).toBeInstanceOf(Array);
|
||||
expect(paths[3][0]).toBe(vertex1);
|
||||
expect(paths[3][1]).toBe(vertex4);
|
||||
expect(paths[3]).toBeInstanceOf(Array);
|
||||
expect(paths[3][0]).toBe(vertex1);
|
||||
expect(paths[3][1]).toBe(vertex4);
|
||||
|
||||
expect(paths[4]).toBeInstanceOf(Array);
|
||||
expect(paths[4][0]).toBe(vertex1);
|
||||
expect(paths[4][1]).toBe(vertex2);
|
||||
expect(paths[4][2]).toBe(vertex3);
|
||||
expect(paths[4][3]).toBe(vertex5);
|
||||
expect(paths[4]).toBeInstanceOf(Array);
|
||||
expect(paths[4][0]).toBe(vertex1);
|
||||
expect(paths[4][1]).toBe(vertex2);
|
||||
expect(paths[4][2]).toBe(vertex3);
|
||||
expect(paths[4][3]).toBe(vertex5);
|
||||
|
||||
expect(paths[5]).toBeInstanceOf(Array);
|
||||
expect(paths[5][0]).toBe(vertex6);
|
||||
expect(paths[5]).toBeInstanceOf(Array);
|
||||
expect(paths[5][0]).toBe(vertex6);
|
||||
|
||||
expect(paths[6]).toBeInstanceOf(Array);
|
||||
expect(paths[6][0]).toBe(vertex1);
|
||||
expect(paths[6][1]).toBe(vertex4);
|
||||
expect(paths[6][2]).toBe(vertex7);
|
||||
expect(paths[6]).toBeInstanceOf(Array);
|
||||
expect(paths[6][0]).toBe(vertex1);
|
||||
expect(paths[6][1]).toBe(vertex4);
|
||||
expect(paths[6][2]).toBe(vertex7);
|
||||
|
||||
expect(paths[7]).toBeInstanceOf(Array);
|
||||
expect(paths[7][0]).toBe(vertex8);
|
||||
expect(paths[7]).toBeInstanceOf(Array);
|
||||
expect(paths[7][0]).toBe(vertex8);
|
||||
|
||||
expect(paths[8]).toBeInstanceOf(Array);
|
||||
expect(paths[8][0]).toBe(vertex1);
|
||||
expect(paths[8][1]).toBe(vertex9);
|
||||
expect(paths[8]).toBeInstanceOf(Array);
|
||||
expect(paths[8][0]).toBe(vertex1);
|
||||
expect(paths[8][1]).toBe(vertex9);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const dijkstraWithoutHeapRes1ntt = myGraph.dijkstraWithoutHeap(1, null, true, true);
|
||||
expect(dijkstraWithoutHeapRes1ntt).toBeTruthy();
|
||||
if (dijkstraWithoutHeapRes1ntt) {
|
||||
const {distMap, minDist, minPath, paths, preMap, seen} = dijkstraWithoutHeapRes1ntt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
expect(distMap.get(vertex2)).toBe(12);
|
||||
expect(distMap.get(vertex3)).toBe(35);
|
||||
expect(distMap.get(vertex4)).toBe(14);
|
||||
expect(distMap.get(vertex5)).toBe(70);
|
||||
expect(distMap.get(vertex6)).toBe(Infinity);
|
||||
expect(distMap.get(vertex7)).toBe(61);
|
||||
expect(distMap.get(vertex8)).toBe(Infinity);
|
||||
expect(distMap.get(vertex9)).toBe(19);
|
||||
const dijkstraWithoutHeapRes1ntt = myGraph.dijkstraWithoutHeap(1, null, true, true);
|
||||
expect(dijkstraWithoutHeapRes1ntt).toBeTruthy();
|
||||
if (dijkstraWithoutHeapRes1ntt) {
|
||||
const {distMap, minDist, minPath, paths, preMap, seen} = dijkstraWithoutHeapRes1ntt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
expect(distMap.get(vertex2)).toBe(12);
|
||||
expect(distMap.get(vertex3)).toBe(35);
|
||||
expect(distMap.get(vertex4)).toBe(14);
|
||||
expect(distMap.get(vertex5)).toBe(70);
|
||||
expect(distMap.get(vertex6)).toBe(Infinity);
|
||||
expect(distMap.get(vertex7)).toBe(61);
|
||||
expect(distMap.get(vertex8)).toBe(Infinity);
|
||||
expect(distMap.get(vertex9)).toBe(19);
|
||||
|
||||
expect(minDist).toBe(12);
|
||||
expect(minPath).toBeInstanceOf(Array);
|
||||
expect(minPath.length).toBe(2);
|
||||
expect(minPath[0]).toBe(vertex1);
|
||||
expect(minPath[1]).toBe(vertex2);
|
||||
expect(minDist).toBe(12);
|
||||
expect(minPath).toBeInstanceOf(Array);
|
||||
expect(minPath.length).toBe(2);
|
||||
expect(minPath[0]).toBe(vertex1);
|
||||
expect(minPath[1]).toBe(vertex2);
|
||||
|
||||
expect(paths).toBeInstanceOf(Array);
|
||||
expect(paths.length).toBe(9);
|
||||
expect(paths[0]).toBeInstanceOf(Array);
|
||||
expect(paths[0][0]).toBe(vertex1);
|
||||
expect(paths).toBeInstanceOf(Array);
|
||||
expect(paths.length).toBe(9);
|
||||
expect(paths[0]).toBeInstanceOf(Array);
|
||||
expect(paths[0][0]).toBe(vertex1);
|
||||
|
||||
expect(paths[1]).toBeInstanceOf(Array);
|
||||
expect(paths[1][0]).toBe(vertex1);
|
||||
expect(paths[1][1]).toBe(vertex2);
|
||||
expect(paths[1]).toBeInstanceOf(Array);
|
||||
expect(paths[1][0]).toBe(vertex1);
|
||||
expect(paths[1][1]).toBe(vertex2);
|
||||
|
||||
expect(paths[2]).toBeInstanceOf(Array);
|
||||
expect(paths[2][0]).toBe(vertex1);
|
||||
expect(paths[2][1]).toBe(vertex2);
|
||||
expect(paths[2][2]).toBe(vertex3);
|
||||
expect(paths[2]).toBeInstanceOf(Array);
|
||||
expect(paths[2][0]).toBe(vertex1);
|
||||
expect(paths[2][1]).toBe(vertex2);
|
||||
expect(paths[2][2]).toBe(vertex3);
|
||||
|
||||
expect(paths[3]).toBeInstanceOf(Array);
|
||||
expect(paths[3][0]).toBe(vertex1);
|
||||
expect(paths[3][1]).toBe(vertex4);
|
||||
expect(paths[3]).toBeInstanceOf(Array);
|
||||
expect(paths[3][0]).toBe(vertex1);
|
||||
expect(paths[3][1]).toBe(vertex4);
|
||||
|
||||
expect(paths[4]).toBeInstanceOf(Array);
|
||||
expect(paths[4][0]).toBe(vertex1);
|
||||
expect(paths[4][1]).toBe(vertex2);
|
||||
expect(paths[4][2]).toBe(vertex3);
|
||||
expect(paths[4][3]).toBe(vertex5);
|
||||
expect(paths[4]).toBeInstanceOf(Array);
|
||||
expect(paths[4][0]).toBe(vertex1);
|
||||
expect(paths[4][1]).toBe(vertex2);
|
||||
expect(paths[4][2]).toBe(vertex3);
|
||||
expect(paths[4][3]).toBe(vertex5);
|
||||
|
||||
expect(paths[5]).toBeInstanceOf(Array);
|
||||
expect(paths[5][0]).toBe(vertex6);
|
||||
expect(paths[5]).toBeInstanceOf(Array);
|
||||
expect(paths[5][0]).toBe(vertex6);
|
||||
|
||||
expect(paths[6]).toBeInstanceOf(Array);
|
||||
expect(paths[6][0]).toBe(vertex1);
|
||||
expect(paths[6][1]).toBe(vertex4);
|
||||
expect(paths[6][2]).toBe(vertex7);
|
||||
expect(paths[6]).toBeInstanceOf(Array);
|
||||
expect(paths[6][0]).toBe(vertex1);
|
||||
expect(paths[6][1]).toBe(vertex4);
|
||||
expect(paths[6][2]).toBe(vertex7);
|
||||
|
||||
expect(paths[7]).toBeInstanceOf(Array);
|
||||
expect(paths[7][0]).toBe(vertex8);
|
||||
expect(paths[7]).toBeInstanceOf(Array);
|
||||
expect(paths[7][0]).toBe(vertex8);
|
||||
|
||||
expect(paths[8]).toBeInstanceOf(Array);
|
||||
expect(paths[8][0]).toBe(vertex1);
|
||||
expect(paths[8][1]).toBe(vertex9);
|
||||
expect(paths[8]).toBeInstanceOf(Array);
|
||||
expect(paths[8][0]).toBe(vertex1);
|
||||
expect(paths[8][1]).toBe(vertex9);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
import {MapGraph, MapVertex} from '../../../../src';
|
||||
|
||||
describe('MapGraph Operation Test', () => {
|
||||
it('dijkstra shortest path', () => {
|
||||
const mapGraph = new MapGraph([5.500338, 100.173665]);
|
||||
it('dijkstra shortest path', () => {
|
||||
const mapGraph = new MapGraph([5.500338, 100.173665]);
|
||||
|
||||
mapGraph.addVertex(new MapVertex('Surin', 5.466724, 100.274805));
|
||||
mapGraph.addVertex(new MapVertex('Batu Feringgi Beach', 5.475141, 100.276670));
|
||||
mapGraph.addVertex(new MapVertex('Lotus', 5.459044, 100.308767));
|
||||
mapGraph.addVertex(new MapVertex('The Breeza', 5.454197, 100.307859));
|
||||
mapGraph.addVertex(new MapVertex('Hard Rock Hotel', 5.467850, 100.241876));
|
||||
mapGraph.addVertex(new MapVertex('Mira', 5.456749, 100.286650));
|
||||
mapGraph.addVertex(new MapVertex('Penang Bible Church', 5.428683, 100.314825));
|
||||
mapGraph.addVertex(new MapVertex('Queensbay', 5.332760, 100.306651));
|
||||
mapGraph.addVertex(new MapVertex('Saanen Goat Farm', 5.405738, 100.207699));
|
||||
mapGraph.addVertex(new MapVertex('Trinity Auto', 5.401126, 100.303739));
|
||||
mapGraph.addVertex(new MapVertex('Penang Airport', 5.293185, 100.265772));
|
||||
mapGraph.addEdge('Surin', 'Lotus', 4.7);
|
||||
mapGraph.addEdge('Lotus', 'The Breeza', 1);
|
||||
mapGraph.addEdge('Batu Feringgi Beach', 'Hard Rock Hotel', 5.2);
|
||||
mapGraph.addEdge('Surin', 'Mira', 2.8);
|
||||
mapGraph.addEdge('Mira', 'Penang Bible Church', 7.0);
|
||||
mapGraph.addEdge('Lotus', 'Penang Bible Church', 5.7);
|
||||
mapGraph.addEdge('Penang Bible Church', 'Queensbay', 13.9);
|
||||
mapGraph.addEdge('Hard Rock Hotel', 'Saanen Goat Farm', 18.5);
|
||||
mapGraph.addEdge('The Breeza', 'Trinity Auto', 9.1);
|
||||
mapGraph.addEdge('Trinity Auto', 'Saanen Goat Farm', 26.3);
|
||||
mapGraph.addEdge('The Breeza', 'Penang Airport', 24.8);
|
||||
mapGraph.addEdge('Penang Airport', 'Saanen Goat Farm', 21.2);
|
||||
const expected1 = ['Surin', 'Lotus', 'The Breeza', 'Trinity Auto', 'Saanen Goat Farm'];
|
||||
mapGraph.addVertex(new MapVertex('Surin', 5.466724, 100.274805));
|
||||
mapGraph.addVertex(new MapVertex('Batu Feringgi Beach', 5.475141, 100.276670));
|
||||
mapGraph.addVertex(new MapVertex('Lotus', 5.459044, 100.308767));
|
||||
mapGraph.addVertex(new MapVertex('The Breeza', 5.454197, 100.307859));
|
||||
mapGraph.addVertex(new MapVertex('Hard Rock Hotel', 5.467850, 100.241876));
|
||||
mapGraph.addVertex(new MapVertex('Mira', 5.456749, 100.286650));
|
||||
mapGraph.addVertex(new MapVertex('Penang Bible Church', 5.428683, 100.314825));
|
||||
mapGraph.addVertex(new MapVertex('Queensbay', 5.332760, 100.306651));
|
||||
mapGraph.addVertex(new MapVertex('Saanen Goat Farm', 5.405738, 100.207699));
|
||||
mapGraph.addVertex(new MapVertex('Trinity Auto', 5.401126, 100.303739));
|
||||
mapGraph.addVertex(new MapVertex('Penang Airport', 5.293185, 100.265772));
|
||||
mapGraph.addEdge('Surin', 'Lotus', 4.7);
|
||||
mapGraph.addEdge('Lotus', 'The Breeza', 1);
|
||||
mapGraph.addEdge('Batu Feringgi Beach', 'Hard Rock Hotel', 5.2);
|
||||
mapGraph.addEdge('Surin', 'Mira', 2.8);
|
||||
mapGraph.addEdge('Mira', 'Penang Bible Church', 7.0);
|
||||
mapGraph.addEdge('Lotus', 'Penang Bible Church', 5.7);
|
||||
mapGraph.addEdge('Penang Bible Church', 'Queensbay', 13.9);
|
||||
mapGraph.addEdge('Hard Rock Hotel', 'Saanen Goat Farm', 18.5);
|
||||
mapGraph.addEdge('The Breeza', 'Trinity Auto', 9.1);
|
||||
mapGraph.addEdge('Trinity Auto', 'Saanen Goat Farm', 26.3);
|
||||
mapGraph.addEdge('The Breeza', 'Penang Airport', 24.8);
|
||||
mapGraph.addEdge('Penang Airport', 'Saanen Goat Farm', 21.2);
|
||||
const expected1 = ['Surin', 'Lotus', 'The Breeza', 'Trinity Auto', 'Saanen Goat Farm'];
|
||||
|
||||
const minPathBetween = mapGraph.getMinPathBetween('Surin', 'Saanen Goat Farm');
|
||||
expect(minPathBetween?.map(v => v.id)).toEqual(expected1);
|
||||
const surinToSaanenGoatFarmDij = mapGraph.dijkstra('Surin', 'Saanen Goat Farm', true, true);
|
||||
expect(surinToSaanenGoatFarmDij?.minPath.map(v => v.id)).toEqual(expected1);
|
||||
expect(surinToSaanenGoatFarmDij?.minDist).toBe(41.1);
|
||||
mapGraph.addEdge('Surin', 'Batu Feringgi Beach', 1.5);
|
||||
const expected2 = ['Surin', 'Batu Feringgi Beach', 'Hard Rock Hotel', 'Saanen Goat Farm'];
|
||||
const minPathBetweenViaBFB = mapGraph.getMinPathBetween('Surin', 'Saanen Goat Farm', true);
|
||||
expect(minPathBetweenViaBFB?.map(v => v.id)).toEqual(expected2);
|
||||
const surinToSaanenGoatFarmViaDij = mapGraph.dijkstra('Surin', 'Saanen Goat Farm', true, true);
|
||||
expect(surinToSaanenGoatFarmViaDij?.minPath.map(v => v.id)).toEqual(expected2);
|
||||
expect(surinToSaanenGoatFarmViaDij?.minDist).toBe(25.2);
|
||||
});
|
||||
const minPathBetween = mapGraph.getMinPathBetween('Surin', 'Saanen Goat Farm');
|
||||
expect(minPathBetween?.map(v => v.id)).toEqual(expected1);
|
||||
const surinToSaanenGoatFarmDij = mapGraph.dijkstra('Surin', 'Saanen Goat Farm', true, true);
|
||||
expect(surinToSaanenGoatFarmDij?.minPath.map(v => v.id)).toEqual(expected1);
|
||||
expect(surinToSaanenGoatFarmDij?.minDist).toBe(41.1);
|
||||
mapGraph.addEdge('Surin', 'Batu Feringgi Beach', 1.5);
|
||||
const expected2 = ['Surin', 'Batu Feringgi Beach', 'Hard Rock Hotel', 'Saanen Goat Farm'];
|
||||
const minPathBetweenViaBFB = mapGraph.getMinPathBetween('Surin', 'Saanen Goat Farm', true);
|
||||
expect(minPathBetweenViaBFB?.map(v => v.id)).toEqual(expected2);
|
||||
const surinToSaanenGoatFarmViaDij = mapGraph.dijkstra('Surin', 'Saanen Goat Farm', true, true);
|
||||
expect(surinToSaanenGoatFarmViaDij?.minPath.map(v => v.id)).toEqual(expected2);
|
||||
expect(surinToSaanenGoatFarmViaDij?.minDist).toBe(25.2);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -2,49 +2,49 @@ import {DirectedGraph, UndirectedGraph} from '../../../../src';
|
|||
|
||||
describe('Overall Graph Operation Test', () => {
|
||||
|
||||
it('Overall DirectedGraph Operation Test', () => {
|
||||
const graph = new DirectedGraph();
|
||||
it('Overall DirectedGraph Operation Test', () => {
|
||||
const graph = new DirectedGraph();
|
||||
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
|
||||
graph.hasVertex('A'); // true
|
||||
graph.hasVertex('B'); // true
|
||||
graph.hasVertex('C'); // false
|
||||
expect(graph.hasVertex('A')).toBe(true); // true
|
||||
expect(graph.hasVertex('B')).toBe(true); // true
|
||||
expect(graph.hasVertex('C')).toBe(false); // false
|
||||
graph.hasVertex('A'); // true
|
||||
graph.hasVertex('B'); // true
|
||||
graph.hasVertex('C'); // false
|
||||
expect(graph.hasVertex('A')).toBe(true); // true
|
||||
expect(graph.hasVertex('B')).toBe(true); // true
|
||||
expect(graph.hasVertex('C')).toBe(false); // false
|
||||
|
||||
graph.addEdge('A', 'B');
|
||||
graph.hasEdge('A', 'B'); // true
|
||||
graph.hasEdge('B', 'A'); // false
|
||||
expect(graph.hasEdge('A', 'B')).toBe(true); // true
|
||||
expect(graph.hasEdge('B', 'A')).toBe(false); // false
|
||||
graph.addEdge('A', 'B');
|
||||
graph.hasEdge('A', 'B'); // true
|
||||
graph.hasEdge('B', 'A'); // false
|
||||
expect(graph.hasEdge('A', 'B')).toBe(true); // true
|
||||
expect(graph.hasEdge('B', 'A')).toBe(false); // false
|
||||
|
||||
graph.removeEdgeSrcToDest('A', 'B');
|
||||
graph.hasEdge('A', 'B'); // false
|
||||
expect(graph.hasEdge('A', 'B')).toBe(false); // false
|
||||
graph.removeEdgeSrcToDest('A', 'B');
|
||||
graph.hasEdge('A', 'B'); // false
|
||||
expect(graph.hasEdge('A', 'B')).toBe(false); // false
|
||||
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('C');
|
||||
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('B', 'C');
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('B', 'C');
|
||||
|
||||
const topologicalOrderIds = graph.topologicalSort();
|
||||
expect(topologicalOrderIds).toEqual(['A', 'B', 'C'])
|
||||
});
|
||||
it('Overall UndirectedGraph Operation Test', () => {
|
||||
const graph = new UndirectedGraph();
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('D');
|
||||
graph.removeVertex('C');
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('B', 'D');
|
||||
const topologicalOrderIds = graph.topologicalSort();
|
||||
expect(topologicalOrderIds).toEqual(['A', 'B', 'C'])
|
||||
});
|
||||
it('Overall UndirectedGraph Operation Test', () => {
|
||||
const graph = new UndirectedGraph();
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('D');
|
||||
graph.removeVertex('C');
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('B', 'D');
|
||||
|
||||
const dijkstraResult = graph.dijkstra('A');
|
||||
Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.id) // ['A', 'B', 'D']
|
||||
expect(Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.id)).toEqual(['A', 'B', 'D']);
|
||||
});
|
||||
const dijkstraResult = graph.dijkstra('A');
|
||||
Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.id) // ['A', 'B', 'D']
|
||||
expect(Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.id)).toEqual(['A', 'B', 'D']);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
import {UndirectedEdge, UndirectedGraph, UndirectedVertex} from '../../../../src';
|
||||
|
||||
describe('UndirectedGraph Operation Test', () => {
|
||||
let graph: UndirectedGraph;
|
||||
let graph: UndirectedGraph;
|
||||
|
||||
beforeEach(() => {
|
||||
graph = new UndirectedGraph();
|
||||
});
|
||||
beforeEach(() => {
|
||||
graph = new UndirectedGraph();
|
||||
});
|
||||
|
||||
|
||||
it('should add vertices', () => {
|
||||
const vertex1 = new UndirectedVertex('A');
|
||||
const vertex2 = new UndirectedVertex('B');
|
||||
it('should add vertices', () => {
|
||||
const vertex1 = new UndirectedVertex('A');
|
||||
const vertex2 = new UndirectedVertex('B');
|
||||
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
|
||||
expect(graph.hasVertex(vertex1)).toBe(true);
|
||||
expect(graph.hasVertex(vertex2)).toBe(true);
|
||||
});
|
||||
expect(graph.hasVertex(vertex1)).toBe(true);
|
||||
expect(graph.hasVertex(vertex2)).toBe(true);
|
||||
});
|
||||
|
||||
it('should add edges', () => {
|
||||
const vertex1 = new UndirectedVertex('A');
|
||||
const vertex2 = new UndirectedVertex('B');
|
||||
const edge = new UndirectedEdge('A', 'B');
|
||||
it('should add edges', () => {
|
||||
const vertex1 = new UndirectedVertex('A');
|
||||
const vertex2 = new UndirectedVertex('B');
|
||||
const edge = new UndirectedEdge('A', 'B');
|
||||
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addEdge(edge);
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addEdge(edge);
|
||||
|
||||
expect(graph.hasEdge('A', 'B')).toBe(true);
|
||||
expect(graph.hasEdge('B', 'A')).toBe(true);
|
||||
});
|
||||
expect(graph.hasEdge('A', 'B')).toBe(true);
|
||||
expect(graph.hasEdge('B', 'A')).toBe(true);
|
||||
});
|
||||
|
||||
it('should remove edges', () => {
|
||||
const vertex1 = new UndirectedVertex('A');
|
||||
const vertex2 = new UndirectedVertex('B');
|
||||
const edge = new UndirectedEdge('A', 'B');
|
||||
it('should remove edges', () => {
|
||||
const vertex1 = new UndirectedVertex('A');
|
||||
const vertex2 = new UndirectedVertex('B');
|
||||
const edge = new UndirectedEdge('A', 'B');
|
||||
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addEdge(edge);
|
||||
graph.addVertex(vertex1);
|
||||
graph.addVertex(vertex2);
|
||||
graph.addEdge(edge);
|
||||
|
||||
expect(graph.removeEdge(edge)).toBe(edge);
|
||||
expect(graph.hasEdge('A', 'B')).toBe(false);
|
||||
});
|
||||
expect(graph.removeEdge(edge)).toBe(edge);
|
||||
expect(graph.hasEdge('A', 'B')).toBe(false);
|
||||
});
|
||||
|
||||
it('should perform topological sort', () => {
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('D');
|
||||
graph.removeVertex('C');
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('B', 'D');
|
||||
it('should perform topological sort', () => {
|
||||
graph.addVertex('A');
|
||||
graph.addVertex('B');
|
||||
graph.addVertex('C');
|
||||
graph.addVertex('D');
|
||||
graph.removeVertex('C');
|
||||
graph.addEdge('A', 'B');
|
||||
graph.addEdge('B', 'D');
|
||||
|
||||
const dijkstraResult = graph.dijkstra('A');
|
||||
expect(Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.id)).toEqual(['A', 'B', 'D']);
|
||||
});
|
||||
const dijkstraResult = graph.dijkstra('A');
|
||||
expect(Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.id)).toEqual(['A', 'B', 'D']);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
import {MaxHeap, MinHeap} from '../../../../src';
|
||||
|
||||
describe('Heap Operation Test', () => {
|
||||
it('should numeric heap work well', function () {
|
||||
const minNumHeap = new MinHeap<number>();
|
||||
minNumHeap.add(1).add(6).add(2).add(0).add(5).add(9);
|
||||
expect(minNumHeap.has(1)).toBe(true);
|
||||
expect(minNumHeap.has(2)).toBe(true);
|
||||
expect(minNumHeap.poll()).toBe(0);
|
||||
expect(minNumHeap.poll()).toBe(1);
|
||||
expect(minNumHeap.peek()).toBe(2);
|
||||
expect(!minNumHeap.has(1));
|
||||
expect(minNumHeap.has(2));
|
||||
const arrFromHeap = minNumHeap.toArray();
|
||||
expect(arrFromHeap.length).toBe(4);
|
||||
expect(arrFromHeap[0]).toBe(2);
|
||||
expect(arrFromHeap[1]).toBe(5);
|
||||
expect(arrFromHeap[2]).toBe(9);
|
||||
expect(arrFromHeap[3]).toBe(6);
|
||||
expect(minNumHeap.sort()).toEqual([2, 5, 6, 9]);
|
||||
});
|
||||
it('should numeric heap work well', function () {
|
||||
const minNumHeap = new MinHeap<number>();
|
||||
minNumHeap.add(1).add(6).add(2).add(0).add(5).add(9);
|
||||
expect(minNumHeap.has(1)).toBe(true);
|
||||
expect(minNumHeap.has(2)).toBe(true);
|
||||
expect(minNumHeap.poll()).toBe(0);
|
||||
expect(minNumHeap.poll()).toBe(1);
|
||||
expect(minNumHeap.peek()).toBe(2);
|
||||
expect(!minNumHeap.has(1));
|
||||
expect(minNumHeap.has(2));
|
||||
const arrFromHeap = minNumHeap.toArray();
|
||||
expect(arrFromHeap.length).toBe(4);
|
||||
expect(arrFromHeap[0]).toBe(2);
|
||||
expect(arrFromHeap[1]).toBe(5);
|
||||
expect(arrFromHeap[2]).toBe(9);
|
||||
expect(arrFromHeap[3]).toBe(6);
|
||||
expect(minNumHeap.sort()).toEqual([2, 5, 6, 9]);
|
||||
});
|
||||
|
||||
it('should object heap work well', function () {
|
||||
const minHeap = new MinHeap<{ a: string }>();
|
||||
minHeap.add(1, {a: 'a1'});
|
||||
minHeap.add(6, {a: 'a6'});
|
||||
minHeap.add(2, {a: 'a2'});
|
||||
minHeap.add(0, {a: 'a0'});
|
||||
it('should object heap work well', function () {
|
||||
const minHeap = new MinHeap<{ a: string }>();
|
||||
minHeap.add(1, {a: 'a1'});
|
||||
minHeap.add(6, {a: 'a6'});
|
||||
minHeap.add(2, {a: 'a2'});
|
||||
minHeap.add(0, {a: 'a0'});
|
||||
|
||||
expect(minHeap.peek()).toEqual({a: 'a0'});
|
||||
expect(minHeap.toArray()).toEqual(([{'a': 'a0'}, {'a': 'a1'}, {'a': 'a2'}, {'a': 'a6'}]));
|
||||
let i = 0;
|
||||
const expectPolled = [{'a': 'a0'}, {'a': 'a1'}, {'a': 'a2'}, {'a': 'a6'}];
|
||||
while (minHeap.size > 0) {
|
||||
expect(minHeap.poll()).toEqual(expectPolled[i]);
|
||||
i++;
|
||||
}
|
||||
expect(minHeap.peek()).toEqual({a: 'a0'});
|
||||
expect(minHeap.toArray()).toEqual(([{'a': 'a0'}, {'a': 'a1'}, {'a': 'a2'}, {'a': 'a6'}]));
|
||||
let i = 0;
|
||||
const expectPolled = [{'a': 'a0'}, {'a': 'a1'}, {'a': 'a2'}, {'a': 'a6'}];
|
||||
while (minHeap.size > 0) {
|
||||
expect(minHeap.poll()).toEqual(expectPolled[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
const maxHeap = new MaxHeap<{ a: string }>();
|
||||
maxHeap.add(1, {a: 'a1'});
|
||||
maxHeap.add(6, {a: 'a6'});
|
||||
maxHeap.add(5, {a: 'a5'});
|
||||
maxHeap.add(2, {a: 'a2'});
|
||||
maxHeap.add(0, {a: 'a0'});
|
||||
maxHeap.add(9, {a: 'a9'});
|
||||
expect(maxHeap.peek()).toEqual({'a': 'a9'});
|
||||
expect(maxHeap.toArray()).toEqual([{'a': 'a9'}, {'a': 'a2'}, {'a': 'a6'}, {'a': 'a1'}, {'a': 'a0'}, {'a': 'a5'}]);
|
||||
const maxExpectPolled = [{'a': 'a9'}, {'a': 'a6'}, {'a': 'a5'}, {'a': 'a2'}, {'a': 'a1'}, {'a': 'a0'}];
|
||||
let maxI = 0;
|
||||
while (maxHeap.size > 0) {
|
||||
expect(maxHeap.poll()).toEqual(maxExpectPolled[maxI]);
|
||||
maxI++;
|
||||
}
|
||||
});
|
||||
const maxHeap = new MaxHeap<{ a: string }>();
|
||||
maxHeap.add(1, {a: 'a1'});
|
||||
maxHeap.add(6, {a: 'a6'});
|
||||
maxHeap.add(5, {a: 'a5'});
|
||||
maxHeap.add(2, {a: 'a2'});
|
||||
maxHeap.add(0, {a: 'a0'});
|
||||
maxHeap.add(9, {a: 'a9'});
|
||||
expect(maxHeap.peek()).toEqual({'a': 'a9'});
|
||||
expect(maxHeap.toArray()).toEqual([{'a': 'a9'}, {'a': 'a2'}, {'a': 'a6'}, {'a': 'a1'}, {'a': 'a0'}, {'a': 'a5'}]);
|
||||
const maxExpectPolled = [{'a': 'a9'}, {'a': 'a6'}, {'a': 'a5'}, {'a': 'a2'}, {'a': 'a1'}, {'a': 'a0'}];
|
||||
let maxI = 0;
|
||||
while (maxHeap.size > 0) {
|
||||
expect(maxHeap.poll()).toEqual(maxExpectPolled[maxI]);
|
||||
maxI++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,41 +2,41 @@ import {HeapItem, MaxHeap} from '../../../../src';
|
|||
|
||||
describe('MaxHeap Operation Test', () => {
|
||||
|
||||
it('should object Max Heap operations be proper', function () {
|
||||
const maxHeap = new MaxHeap<{ keyA: string }>();
|
||||
const myObj1 = {keyA: 'a1'}, myObj6 = {keyA: 'a6'}, myObj5 = {keyA: 'a5'}, myObj2 = {keyA: 'a2'},
|
||||
myObj0 = {keyA: 'a0'}, myObj9 = {keyA: 'a9'};
|
||||
maxHeap.add(1, myObj1);
|
||||
expect(maxHeap.has(myObj1)).toBe(true);
|
||||
expect(maxHeap.has(myObj9)).toBe(false);
|
||||
maxHeap.add(6, myObj6);
|
||||
expect(maxHeap.has(myObj6)).toBe(true);
|
||||
maxHeap.add(5, myObj5);
|
||||
expect(maxHeap.has(myObj5)).toBe(true);
|
||||
maxHeap.add(2, myObj2);
|
||||
expect(maxHeap.has(myObj2)).toBe(true);
|
||||
expect(maxHeap.has(myObj6)).toBe(true);
|
||||
maxHeap.add(0, myObj0);
|
||||
expect(maxHeap.has(myObj0)).toBe(true);
|
||||
expect(maxHeap.has(myObj9)).toBe(false);
|
||||
maxHeap.add(9, myObj9);
|
||||
expect(maxHeap.has(myObj9)).toBe(true);
|
||||
it('should object Max Heap operations be proper', function () {
|
||||
const maxHeap = new MaxHeap<{ keyA: string }>();
|
||||
const myObj1 = {keyA: 'a1'}, myObj6 = {keyA: 'a6'}, myObj5 = {keyA: 'a5'}, myObj2 = {keyA: 'a2'},
|
||||
myObj0 = {keyA: 'a0'}, myObj9 = {keyA: 'a9'};
|
||||
maxHeap.add(1, myObj1);
|
||||
expect(maxHeap.has(myObj1)).toBe(true);
|
||||
expect(maxHeap.has(myObj9)).toBe(false);
|
||||
maxHeap.add(6, myObj6);
|
||||
expect(maxHeap.has(myObj6)).toBe(true);
|
||||
maxHeap.add(5, myObj5);
|
||||
expect(maxHeap.has(myObj5)).toBe(true);
|
||||
maxHeap.add(2, myObj2);
|
||||
expect(maxHeap.has(myObj2)).toBe(true);
|
||||
expect(maxHeap.has(myObj6)).toBe(true);
|
||||
maxHeap.add(0, myObj0);
|
||||
expect(maxHeap.has(myObj0)).toBe(true);
|
||||
expect(maxHeap.has(myObj9)).toBe(false);
|
||||
maxHeap.add(9, myObj9);
|
||||
expect(maxHeap.has(myObj9)).toBe(true);
|
||||
|
||||
const peek9 = maxHeap.peek(true);
|
||||
peek9 && peek9.val && expect(peek9.val.keyA).toBe('a9');
|
||||
const peek9 = maxHeap.peek(true);
|
||||
peek9 && peek9.val && expect(peek9.val.keyA).toBe('a9');
|
||||
|
||||
const heapToArr = maxHeap.toArray(true);
|
||||
expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a9', 'a2', 'a6', 'a1', 'a0', 'a5']);
|
||||
const heapToArr = maxHeap.toArray(true);
|
||||
expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a9', 'a2', 'a6', 'a1', 'a0', 'a5']);
|
||||
|
||||
const values = ['a9', 'a6', 'a5', 'a2', 'a1', 'a0'];
|
||||
let i = 0;
|
||||
while (maxHeap.size > 0) {
|
||||
const polled = maxHeap.poll(true);
|
||||
expect(polled).toBeInstanceOf(HeapItem);
|
||||
polled && expect(polled.val).toHaveProperty('keyA');
|
||||
polled && polled.val && expect(polled.val.keyA).toBe(values[i]);
|
||||
i++;
|
||||
}
|
||||
});
|
||||
const values = ['a9', 'a6', 'a5', 'a2', 'a1', 'a0'];
|
||||
let i = 0;
|
||||
while (maxHeap.size > 0) {
|
||||
const polled = maxHeap.poll(true);
|
||||
expect(polled).toBeInstanceOf(HeapItem);
|
||||
polled && expect(polled.val).toHaveProperty('keyA');
|
||||
polled && polled.val && expect(polled.val.keyA).toBe(values[i]);
|
||||
i++;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,80 +2,80 @@ import {HeapItem, MinHeap} from '../../../../src';
|
|||
|
||||
describe('MinHeap Operation Test', () => {
|
||||
|
||||
it('should numeric Min Heap operations be proper', function () {
|
||||
const minNumHeap = new MinHeap<number>();
|
||||
expect(minNumHeap).toBeInstanceOf(MinHeap);
|
||||
it('should numeric Min Heap operations be proper', function () {
|
||||
const minNumHeap = new MinHeap<number>();
|
||||
expect(minNumHeap).toBeInstanceOf(MinHeap);
|
||||
|
||||
minNumHeap.add(1);
|
||||
expect(minNumHeap.has(1)).toBe(true);
|
||||
minNumHeap.add(6);
|
||||
expect(minNumHeap.has(2)).toBe(false);
|
||||
expect(minNumHeap.has(6)).toBe(true);
|
||||
minNumHeap.add(2);
|
||||
expect(minNumHeap.has(2)).toBe(true);
|
||||
minNumHeap.add(0);
|
||||
expect(minNumHeap.has(0)).toBe(true);
|
||||
minNumHeap.add(5);
|
||||
expect(minNumHeap.has(5)).toBe(true);
|
||||
minNumHeap.add(9);
|
||||
expect(minNumHeap.has(9)).toBe(true);
|
||||
expect(minNumHeap.size).toBe(6);
|
||||
minNumHeap.add(1);
|
||||
expect(minNumHeap.has(1)).toBe(true);
|
||||
minNumHeap.add(6);
|
||||
expect(minNumHeap.has(2)).toBe(false);
|
||||
expect(minNumHeap.has(6)).toBe(true);
|
||||
minNumHeap.add(2);
|
||||
expect(minNumHeap.has(2)).toBe(true);
|
||||
minNumHeap.add(0);
|
||||
expect(minNumHeap.has(0)).toBe(true);
|
||||
minNumHeap.add(5);
|
||||
expect(minNumHeap.has(5)).toBe(true);
|
||||
minNumHeap.add(9);
|
||||
expect(minNumHeap.has(9)).toBe(true);
|
||||
expect(minNumHeap.size).toBe(6);
|
||||
|
||||
const poll1 = minNumHeap.poll(true);
|
||||
expect(poll1).toBeInstanceOf(HeapItem)
|
||||
poll1 instanceof HeapItem && expect(poll1.val).toBe(0);
|
||||
const poll1 = minNumHeap.poll(true);
|
||||
expect(poll1).toBeInstanceOf(HeapItem)
|
||||
poll1 instanceof HeapItem && expect(poll1.val).toBe(0);
|
||||
|
||||
const poll2 = minNumHeap.poll(true);
|
||||
expect(poll2).toBeInstanceOf(HeapItem)
|
||||
poll2 instanceof HeapItem && expect(poll2.val).toBe(1);
|
||||
const poll2 = minNumHeap.poll(true);
|
||||
expect(poll2).toBeInstanceOf(HeapItem)
|
||||
poll2 instanceof HeapItem && expect(poll2.val).toBe(1);
|
||||
|
||||
const peek1 = minNumHeap.peek(true);
|
||||
expect(peek1).toBeInstanceOf(HeapItem)
|
||||
peek1 instanceof HeapItem && expect(peek1.val).toBe(2);
|
||||
const peek1 = minNumHeap.peek(true);
|
||||
expect(peek1).toBeInstanceOf(HeapItem)
|
||||
peek1 instanceof HeapItem && expect(peek1.val).toBe(2);
|
||||
|
||||
const heapArray = minNumHeap.toArray(true);
|
||||
expect(heapArray).toBeInstanceOf(Array);
|
||||
expect(heapArray.map(item => item?.priority)).toEqual([2, 5, 9, 6]);
|
||||
expect(minNumHeap.size).toBe(4);
|
||||
});
|
||||
const heapArray = minNumHeap.toArray(true);
|
||||
expect(heapArray).toBeInstanceOf(Array);
|
||||
expect(heapArray.map(item => item?.priority)).toEqual([2, 5, 9, 6]);
|
||||
expect(minNumHeap.size).toBe(4);
|
||||
});
|
||||
|
||||
it('should object Min Heap operations be proper', function () {
|
||||
class MyObject {
|
||||
keyA: string;
|
||||
it('should object Min Heap operations be proper', function () {
|
||||
class MyObject {
|
||||
keyA: string;
|
||||
|
||||
constructor(keyA: string) {
|
||||
this.keyA = keyA;
|
||||
}
|
||||
}
|
||||
constructor(keyA: string) {
|
||||
this.keyA = keyA;
|
||||
}
|
||||
}
|
||||
|
||||
const minObjHeap = new MinHeap<MyObject>();
|
||||
const minObjHeap = new MinHeap<MyObject>();
|
||||
|
||||
const obj1 = new MyObject('a1'), obj6 = new MyObject('a6'), obj2 = new MyObject('a2'),
|
||||
obj0 = new MyObject('a0');
|
||||
minObjHeap.add(1, obj1);
|
||||
expect(minObjHeap.has(obj1)).toBe(true);
|
||||
expect(minObjHeap.has(obj6)).toBe(false);
|
||||
minObjHeap.add(6, obj6);
|
||||
expect(minObjHeap.has(obj6)).toBe(true);
|
||||
minObjHeap.add(2, obj2);
|
||||
expect(minObjHeap.has(obj2)).toBe(true);
|
||||
minObjHeap.add(0, obj0);
|
||||
expect(minObjHeap.has(obj0)).toBe(true);
|
||||
const obj1 = new MyObject('a1'), obj6 = new MyObject('a6'), obj2 = new MyObject('a2'),
|
||||
obj0 = new MyObject('a0');
|
||||
minObjHeap.add(1, obj1);
|
||||
expect(minObjHeap.has(obj1)).toBe(true);
|
||||
expect(minObjHeap.has(obj6)).toBe(false);
|
||||
minObjHeap.add(6, obj6);
|
||||
expect(minObjHeap.has(obj6)).toBe(true);
|
||||
minObjHeap.add(2, obj2);
|
||||
expect(minObjHeap.has(obj2)).toBe(true);
|
||||
minObjHeap.add(0, obj0);
|
||||
expect(minObjHeap.has(obj0)).toBe(true);
|
||||
|
||||
const peek = minObjHeap.peek(true);
|
||||
peek && peek.val && expect(peek.val.keyA).toBe('a0');
|
||||
const peek = minObjHeap.peek(true);
|
||||
peek && peek.val && expect(peek.val.keyA).toBe('a0');
|
||||
|
||||
const heapToArr = minObjHeap.toArray(true);
|
||||
expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a0', 'a1', 'a2', 'a6']);
|
||||
const heapToArr = minObjHeap.toArray(true);
|
||||
expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a0', 'a1', 'a2', 'a6']);
|
||||
|
||||
const values = ['a0', 'a1', 'a2', 'a6'];
|
||||
let i = 0;
|
||||
while (minObjHeap.size > 0) {
|
||||
const polled = minObjHeap.poll(true);
|
||||
expect(polled).toBeInstanceOf(HeapItem);
|
||||
polled && expect(polled.val).toBeInstanceOf(MyObject);
|
||||
polled && polled.val && expect(polled.val.keyA).toBe(values[i]);
|
||||
i++;
|
||||
}
|
||||
});
|
||||
});
|
||||
const values = ['a0', 'a1', 'a2', 'a6'];
|
||||
let i = 0;
|
||||
while (minObjHeap.size > 0) {
|
||||
const polled = minObjHeap.poll(true);
|
||||
expect(polled).toBeInstanceOf(HeapItem);
|
||||
polled && expect(polled.val).toBeInstanceOf(MyObject);
|
||||
polled && polled.val && expect(polled.val.keyA).toBe(values[i]);
|
||||
i++;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,365 +1,365 @@
|
|||
import {DoublyLinkedList} from '../../../../src';
|
||||
import {magnitude} from '../constants';
|
||||
|
||||
describe('DoublyLinkedList Operation Test', () => {
|
||||
let list: DoublyLinkedList<number>;
|
||||
let objectList: DoublyLinkedList<{ keyA: number }>;
|
||||
|
||||
beforeEach(() => {
|
||||
list = new DoublyLinkedList();
|
||||
objectList = new DoublyLinkedList();
|
||||
});
|
||||
|
||||
it('should initialize an empty list', () => {
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.head).toBeNull();
|
||||
expect(list.tail).toBeNull();
|
||||
});
|
||||
|
||||
it('should push elements to the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
expect(list.length).toBe(3);
|
||||
expect(list.head!.val).toBe(1);
|
||||
expect(list.tail!.val).toBe(3);
|
||||
});
|
||||
|
||||
it('should pop elements from the end of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const poppedValue = list.pop();
|
||||
expect(poppedValue).toBe(2);
|
||||
expect(list.length).toBe(1);
|
||||
expect(list.head!.val).toBe(1);
|
||||
expect(list.tail!.val).toBe(1);
|
||||
});
|
||||
it('should insert elements at specific positions', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
// Inserting at the beginning
|
||||
list.insertAt(0, 0);
|
||||
expect(list.length).toBe(4);
|
||||
expect(list.getAt(0)).toBe(0);
|
||||
expect(list.getAt(1)).toBe(1);
|
||||
|
||||
// Inserting in the middle
|
||||
list.insertAt(2, 1.5);
|
||||
expect(list.length).toBe(5);
|
||||
expect(list.getAt(2)).toBe(1.5);
|
||||
expect(list.getAt(3)).toBe(2);
|
||||
|
||||
// Inserting at the end
|
||||
list.insertAt(5, 4);
|
||||
expect(list.length).toBe(6);
|
||||
expect(list.getAt(5)).toBe(4);
|
||||
expect(list.tail!.val).toBe(4);
|
||||
});
|
||||
|
||||
it('should delete elements at specific positions', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
// Deleting from the beginning
|
||||
const deletedValue = list.deleteAt(0);
|
||||
expect(deletedValue).toBe(1);
|
||||
expect(list.length).toBe(2);
|
||||
expect(list.head!.val).toBe(2);
|
||||
|
||||
// Deleting from the middle
|
||||
list.deleteAt(0); // Deleting the second element
|
||||
expect(list.length).toBe(1);
|
||||
expect(list.head!.val).toBe(3);
|
||||
|
||||
// Deleting from the end
|
||||
list.deleteAt(0);
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.head).toBeNull();
|
||||
expect(list.tail).toBeNull();
|
||||
});
|
||||
|
||||
it('should delete elements by value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.delete(2);
|
||||
expect(list.length).toBe(2);
|
||||
expect(list.head!.val).toBe(1);
|
||||
expect(list.tail!.val).toBe(3);
|
||||
|
||||
list.delete(1);
|
||||
expect(list.length).toBe(1);
|
||||
expect(list.head!.val).toBe(3);
|
||||
|
||||
list.delete(3);
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.head).toBeNull();
|
||||
expect(list.tail).toBeNull();
|
||||
});
|
||||
|
||||
it('should reverse the linked list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.reverse();
|
||||
|
||||
expect(list.toArray()).toEqual([3, 2, 1]);
|
||||
expect(list.toArrayReverse()).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should map elements using a callback function', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const mappedList = list.map((val) => val * 2);
|
||||
|
||||
expect(mappedList.toArray()).toEqual([2, 4, 6]);
|
||||
});
|
||||
|
||||
it('should filter elements using a callback function', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.push(4);
|
||||
|
||||
const filteredList = list.filter((val) => val % 2 === 0);
|
||||
|
||||
expect(filteredList.toArray()).toEqual([2, 4]);
|
||||
});
|
||||
|
||||
it('should reduce elements using a callback function and an initial value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.push(4);
|
||||
|
||||
const sum = list.reduce((acc, val) => acc + val, 0);
|
||||
|
||||
expect(sum).toBe(10);
|
||||
});
|
||||
|
||||
it('should insert an element after a specific value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.insertAfter(2, 2.5);
|
||||
|
||||
expect(list.toArray()).toEqual([1, 2, 2.5, 3]);
|
||||
});
|
||||
|
||||
it('should insert an element before a specific value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.insertBefore(2, 1.5);
|
||||
|
||||
expect(list.toArray()).toEqual([1, 1.5, 2, 3]);
|
||||
});
|
||||
it('should find the first element that satisfies a condition', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const found = list.find((val) => val % 2 === 0);
|
||||
|
||||
expect(found).toBe(2);
|
||||
});
|
||||
|
||||
it('should find the index of an element', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const index = list.indexOf(2);
|
||||
|
||||
expect(index).toBe(1);
|
||||
});
|
||||
|
||||
it('should find the last element that satisfies a condition', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.push(4);
|
||||
|
||||
const lastEven = list.findLast((val) => val % 2 === 0);
|
||||
|
||||
expect(lastEven).toBe(4);
|
||||
});
|
||||
|
||||
it('should clear the linked list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.clear();
|
||||
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.head).toBe(null);
|
||||
expect(list.tail).toBe(null);
|
||||
});
|
||||
|
||||
it('should create a reversed array of values', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const reversedArray = list.toArrayReverse();
|
||||
|
||||
expect(reversedArray).toEqual([3, 2, 1]);
|
||||
});
|
||||
|
||||
it('should reverse the linked list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.reverse();
|
||||
|
||||
expect(list.toArray()).toEqual([3, 2, 1]);
|
||||
expect(list.head?.val).toBe(3);
|
||||
expect(list.tail?.val).toBe(1);
|
||||
});
|
||||
|
||||
it('should iterate over each element and apply a callback', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const result: number[] = [];
|
||||
list.forEach((val) => {
|
||||
result.push(val * 2);
|
||||
});
|
||||
|
||||
expect(result).toEqual([2, 4, 6]);
|
||||
});
|
||||
|
||||
it('should create a new linked list by applying a mapping function', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const mappedList = list.map((val) => val * 2);
|
||||
|
||||
expect(mappedList.toArray()).toEqual([2, 4, 6]);
|
||||
});
|
||||
|
||||
it('should create a new linked list by filtering elements', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.push(4);
|
||||
|
||||
const filteredList = list.filter((val) => val % 2 === 0);
|
||||
|
||||
expect(filteredList.toArray()).toEqual([2, 4]);
|
||||
});
|
||||
|
||||
it('should reduce the linked list to a single value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const sum = list.reduce((acc, val) => acc + val, 0);
|
||||
|
||||
expect(sum).toBe(6);
|
||||
});
|
||||
|
||||
it('should insert a new value after an existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const success = list.insertAfter(2, 4);
|
||||
expect(success).toBe(true);
|
||||
expect(list.toArray()).toEqual([1, 2, 4, 3]);
|
||||
});
|
||||
|
||||
it('should insert a new value before an existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const success = list.insertBefore(2, 0);
|
||||
expect(success).toBe(true);
|
||||
expect(list.toArray()).toEqual([1, 0, 2, 3]);
|
||||
});
|
||||
|
||||
it('should not insert a new value after a non-existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const success = list.insertAfter(4, 5);
|
||||
expect(success).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should not insert a new value before a non-existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const success = list.insertBefore(4, 0);
|
||||
expect(success).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should insert and manipulate objects with numeric properties', () => {
|
||||
const obj1 = {keyA: 10};
|
||||
const obj2 = {keyA: 20};
|
||||
const obj3 = {keyA: 30};
|
||||
|
||||
objectList.push(obj1);
|
||||
objectList.push(obj2);
|
||||
objectList.push(obj3);
|
||||
|
||||
expect(objectList.toArray()).toEqual([obj1, obj2, obj3]);
|
||||
|
||||
const newObj = {keyA: 25}; // Corrected newObj value
|
||||
const insertSuccess = objectList.insertBefore(obj2, newObj);
|
||||
expect(insertSuccess).toBe(true);
|
||||
|
||||
const findNode = objectList.findNode(newObj); // Use newObj instead of obj2
|
||||
expect(findNode?.val).toEqual(newObj);
|
||||
|
||||
const deleted = objectList.delete(newObj); // Use newObj instead of obj2
|
||||
expect(deleted).toBe(true);
|
||||
|
||||
const poppedObj = objectList.pop();
|
||||
expect(poppedObj).toBe(obj3);
|
||||
|
||||
const shiftedObj = objectList.shift();
|
||||
expect(shiftedObj).toBe(obj1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('DoublyLinkedList Performance Test', () => {
|
||||
describe('should the push and pop methods adhere to a time complexity of O(n) and executed correctly under large scale data', () => {
|
||||
const list = new DoublyLinkedList<number>();
|
||||
|
||||
const startPushTime = performance.now();
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
list.unshift(i);
|
||||
}
|
||||
expect(performance.now() - startPushTime).toBeLessThan(magnitude.LINEAR * 1000);
|
||||
|
||||
const startPopTime = performance.now();
|
||||
|
||||
expect(list.length).toBeGreaterThan(0);
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
list.shift();
|
||||
}
|
||||
expect(list.pop()).toBeNull();
|
||||
expect(list.length).toBe(0);
|
||||
expect(performance.now() - startPopTime).toBeLessThan(magnitude.LINEAR * 1000);
|
||||
});
|
||||
});
|
||||
import {DoublyLinkedList} from '../../../../src';
|
||||
import {bigO, magnitude} from '../../../utils';
|
||||
|
||||
describe('DoublyLinkedList Operation Test', () => {
|
||||
let list: DoublyLinkedList<number>;
|
||||
let objectList: DoublyLinkedList<{ keyA: number }>;
|
||||
|
||||
beforeEach(() => {
|
||||
list = new DoublyLinkedList();
|
||||
objectList = new DoublyLinkedList();
|
||||
});
|
||||
|
||||
it('should initialize an empty list', () => {
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.head).toBeNull();
|
||||
expect(list.tail).toBeNull();
|
||||
});
|
||||
|
||||
it('should push elements to the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
expect(list.length).toBe(3);
|
||||
expect(list.head!.val).toBe(1);
|
||||
expect(list.tail!.val).toBe(3);
|
||||
});
|
||||
|
||||
it('should pop elements from the end of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const poppedValue = list.pop();
|
||||
expect(poppedValue).toBe(2);
|
||||
expect(list.length).toBe(1);
|
||||
expect(list.head!.val).toBe(1);
|
||||
expect(list.tail!.val).toBe(1);
|
||||
});
|
||||
it('should insert elements at specific positions', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
// Inserting at the beginning
|
||||
list.insertAt(0, 0);
|
||||
expect(list.length).toBe(4);
|
||||
expect(list.getAt(0)).toBe(0);
|
||||
expect(list.getAt(1)).toBe(1);
|
||||
|
||||
// Inserting in the middle
|
||||
list.insertAt(2, 1.5);
|
||||
expect(list.length).toBe(5);
|
||||
expect(list.getAt(2)).toBe(1.5);
|
||||
expect(list.getAt(3)).toBe(2);
|
||||
|
||||
// Inserting at the end
|
||||
list.insertAt(5, 4);
|
||||
expect(list.length).toBe(6);
|
||||
expect(list.getAt(5)).toBe(4);
|
||||
expect(list.tail!.val).toBe(4);
|
||||
});
|
||||
|
||||
it('should delete elements at specific positions', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
// Deleting from the beginning
|
||||
const deletedValue = list.deleteAt(0);
|
||||
expect(deletedValue).toBe(1);
|
||||
expect(list.length).toBe(2);
|
||||
expect(list.head!.val).toBe(2);
|
||||
|
||||
// Deleting from the middle
|
||||
list.deleteAt(0); // Deleting the second element
|
||||
expect(list.length).toBe(1);
|
||||
expect(list.head!.val).toBe(3);
|
||||
|
||||
// Deleting from the end
|
||||
list.deleteAt(0);
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.head).toBeNull();
|
||||
expect(list.tail).toBeNull();
|
||||
});
|
||||
|
||||
it('should delete elements by value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.delete(2);
|
||||
expect(list.length).toBe(2);
|
||||
expect(list.head!.val).toBe(1);
|
||||
expect(list.tail!.val).toBe(3);
|
||||
|
||||
list.delete(1);
|
||||
expect(list.length).toBe(1);
|
||||
expect(list.head!.val).toBe(3);
|
||||
|
||||
list.delete(3);
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.head).toBeNull();
|
||||
expect(list.tail).toBeNull();
|
||||
});
|
||||
|
||||
it('should reverse the linked list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.reverse();
|
||||
|
||||
expect(list.toArray()).toEqual([3, 2, 1]);
|
||||
expect(list.toArrayReverse()).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should map elements using a callback function', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const mappedList = list.map((val) => val * 2);
|
||||
|
||||
expect(mappedList.toArray()).toEqual([2, 4, 6]);
|
||||
});
|
||||
|
||||
it('should filter elements using a callback function', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.push(4);
|
||||
|
||||
const filteredList = list.filter((val) => val % 2 === 0);
|
||||
|
||||
expect(filteredList.toArray()).toEqual([2, 4]);
|
||||
});
|
||||
|
||||
it('should reduce elements using a callback function and an initial value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.push(4);
|
||||
|
||||
const sum = list.reduce((acc, val) => acc + val, 0);
|
||||
|
||||
expect(sum).toBe(10);
|
||||
});
|
||||
|
||||
it('should insert an element after a specific value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.insertAfter(2, 2.5);
|
||||
|
||||
expect(list.toArray()).toEqual([1, 2, 2.5, 3]);
|
||||
});
|
||||
|
||||
it('should insert an element before a specific value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.insertBefore(2, 1.5);
|
||||
|
||||
expect(list.toArray()).toEqual([1, 1.5, 2, 3]);
|
||||
});
|
||||
it('should find the first element that satisfies a condition', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const found = list.find((val) => val % 2 === 0);
|
||||
|
||||
expect(found).toBe(2);
|
||||
});
|
||||
|
||||
it('should find the index of an element', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const index = list.indexOf(2);
|
||||
|
||||
expect(index).toBe(1);
|
||||
});
|
||||
|
||||
it('should find the last element that satisfies a condition', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.push(4);
|
||||
|
||||
const lastEven = list.findLast((val) => val % 2 === 0);
|
||||
|
||||
expect(lastEven).toBe(4);
|
||||
});
|
||||
|
||||
it('should clear the linked list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.clear();
|
||||
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.head).toBe(null);
|
||||
expect(list.tail).toBe(null);
|
||||
});
|
||||
|
||||
it('should create a reversed array of values', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const reversedArray = list.toArrayReverse();
|
||||
|
||||
expect(reversedArray).toEqual([3, 2, 1]);
|
||||
});
|
||||
|
||||
it('should reverse the linked list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
list.reverse();
|
||||
|
||||
expect(list.toArray()).toEqual([3, 2, 1]);
|
||||
expect(list.head?.val).toBe(3);
|
||||
expect(list.tail?.val).toBe(1);
|
||||
});
|
||||
|
||||
it('should iterate over each element and apply a callback', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const result: number[] = [];
|
||||
list.forEach((val) => {
|
||||
result.push(val * 2);
|
||||
});
|
||||
|
||||
expect(result).toEqual([2, 4, 6]);
|
||||
});
|
||||
|
||||
it('should create a new linked list by applying a mapping function', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const mappedList = list.map((val) => val * 2);
|
||||
|
||||
expect(mappedList.toArray()).toEqual([2, 4, 6]);
|
||||
});
|
||||
|
||||
it('should create a new linked list by filtering elements', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.push(4);
|
||||
|
||||
const filteredList = list.filter((val) => val % 2 === 0);
|
||||
|
||||
expect(filteredList.toArray()).toEqual([2, 4]);
|
||||
});
|
||||
|
||||
it('should reduce the linked list to a single value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const sum = list.reduce((acc, val) => acc + val, 0);
|
||||
|
||||
expect(sum).toBe(6);
|
||||
});
|
||||
|
||||
it('should insert a new value after an existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const success = list.insertAfter(2, 4);
|
||||
expect(success).toBe(true);
|
||||
expect(list.toArray()).toEqual([1, 2, 4, 3]);
|
||||
});
|
||||
|
||||
it('should insert a new value before an existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const success = list.insertBefore(2, 0);
|
||||
expect(success).toBe(true);
|
||||
expect(list.toArray()).toEqual([1, 0, 2, 3]);
|
||||
});
|
||||
|
||||
it('should not insert a new value after a non-existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const success = list.insertAfter(4, 5);
|
||||
expect(success).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should not insert a new value before a non-existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
|
||||
const success = list.insertBefore(4, 0);
|
||||
expect(success).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('should insert and manipulate objects with numeric properties', () => {
|
||||
const obj1 = {keyA: 10};
|
||||
const obj2 = {keyA: 20};
|
||||
const obj3 = {keyA: 30};
|
||||
|
||||
objectList.push(obj1);
|
||||
objectList.push(obj2);
|
||||
objectList.push(obj3);
|
||||
|
||||
expect(objectList.toArray()).toEqual([obj1, obj2, obj3]);
|
||||
|
||||
const newObj = {keyA: 25}; // Corrected newObj value
|
||||
const insertSuccess = objectList.insertBefore(obj2, newObj);
|
||||
expect(insertSuccess).toBe(true);
|
||||
|
||||
const findNode = objectList.findNode(newObj); // Use newObj instead of obj2
|
||||
expect(findNode?.val).toEqual(newObj);
|
||||
|
||||
const deleted = objectList.delete(newObj); // Use newObj instead of obj2
|
||||
expect(deleted).toBe(true);
|
||||
|
||||
const poppedObj = objectList.pop();
|
||||
expect(poppedObj).toBe(obj3);
|
||||
|
||||
const shiftedObj = objectList.shift();
|
||||
expect(shiftedObj).toBe(obj1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('DoublyLinkedList Performance Test', () => {
|
||||
it('should the push and pop methods adhere to a time complexity of O(n) and executed correctly under large scale data', () => {
|
||||
const list = new DoublyLinkedList<number>();
|
||||
|
||||
const startPushTime = performance.now();
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
list.unshift(i);
|
||||
}
|
||||
expect(performance.now() - startPushTime).toBeLessThan(bigO.LINEAR * 10);
|
||||
|
||||
expect(list.length).toBeGreaterThan(0);
|
||||
const startPopTime = performance.now();
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
list.shift();
|
||||
}
|
||||
expect(performance.now() - startPopTime).toBeLessThan(bigO.LINEAR * 10);
|
||||
|
||||
expect(list.pop()).toBeUndefined();
|
||||
expect(list.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
import {DoublyLinkedList, DoublyLinkedListNode, SinglyLinkedList, SinglyLinkedListNode} from '../../../../src';
|
||||
import {magnitude} from '../constants';
|
||||
import {bigO, magnitude} from '../../../utils';
|
||||
|
||||
describe('LinkedList Performance Test', () => {
|
||||
it('should DoublyLinkedList insertBefore faster than SinglyLinkedList', () => {
|
||||
const doublyList = new DoublyLinkedList<number>();
|
||||
it('should DoublyLinkedList insertBefore faster than SinglyLinkedList', () => {
|
||||
const doublyList = new DoublyLinkedList<number>();
|
||||
|
||||
const startPushTime = performance.now();
|
||||
let midNode: DoublyLinkedListNode | null = null;
|
||||
const midIndex = Math.floor((magnitude.SQUARED) / 2);
|
||||
for (let i = 0; i < magnitude.SQUARED; i++) {
|
||||
doublyList.push(i);
|
||||
if (i === midIndex) {
|
||||
midNode = doublyList.findNode(i);
|
||||
} else if (i > midIndex && midNode) {
|
||||
doublyList.insertBefore(midNode, i);
|
||||
}
|
||||
}
|
||||
const doublyListPushCost = performance.now() - startPushTime;
|
||||
const startPushTime = performance.now();
|
||||
let midNode: DoublyLinkedListNode | null = null;
|
||||
const midIndex = Math.floor((magnitude.SQUARED) / 2);
|
||||
for (let i = 0; i < magnitude.SQUARED; i++) {
|
||||
doublyList.push(i);
|
||||
if (i === midIndex) {
|
||||
midNode = doublyList.findNode(i);
|
||||
} else if (i > midIndex && midNode) {
|
||||
doublyList.insertBefore(midNode, i);
|
||||
}
|
||||
}
|
||||
const doublyListPushCost = performance.now() - startPushTime;
|
||||
|
||||
const singlyList = new SinglyLinkedList<number>();
|
||||
let midSinglyNode: SinglyLinkedListNode | null = null;
|
||||
const singlyList = new SinglyLinkedList<number>();
|
||||
let midSinglyNode: SinglyLinkedListNode | null = null;
|
||||
|
||||
const startSinglyPushTime = performance.now();
|
||||
for (let i = 0; i < magnitude.SQUARED; i++) {
|
||||
singlyList.push(i);
|
||||
if (i === midIndex) {
|
||||
midSinglyNode = singlyList.findNode(i);
|
||||
} else if (i > midIndex && midSinglyNode) {
|
||||
singlyList.insertBefore(midSinglyNode.val, i);
|
||||
}
|
||||
}
|
||||
const startSinglyPushTime = performance.now();
|
||||
for (let i = 0; i < magnitude.SQUARED; i++) {
|
||||
singlyList.push(i);
|
||||
if (i === midIndex) {
|
||||
midSinglyNode = singlyList.findNode(i);
|
||||
} else if (i > midIndex && midSinglyNode) {
|
||||
singlyList.insertBefore(midSinglyNode.val, i);
|
||||
}
|
||||
}
|
||||
|
||||
const singlyListPushCost = performance.now() - startSinglyPushTime;
|
||||
expect(doublyListPushCost).toBeLessThan(Math.sqrt(singlyListPushCost) + 1000);
|
||||
});
|
||||
});
|
||||
const singlyListPushCost = performance.now() - startSinglyPushTime;
|
||||
expect(doublyListPushCost).toBeLessThan(bigO.SQUARED * 2);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,401 +1,401 @@
|
|||
import {SinglyLinkedList} from '../../../../src';
|
||||
import {magnitude} from '../constants';
|
||||
import {bigO, magnitude} from '../../../utils';
|
||||
|
||||
describe('SinglyLinkedList Operation Test', () => {
|
||||
let list: SinglyLinkedList<number>;
|
||||
let objectList: SinglyLinkedList<{ keyA: number }>;
|
||||
beforeEach(() => {
|
||||
list = new SinglyLinkedList<number>();
|
||||
objectList = new SinglyLinkedList<{ keyA: number }>();
|
||||
let list: SinglyLinkedList<number>;
|
||||
let objectList: SinglyLinkedList<{ keyA: number }>;
|
||||
beforeEach(() => {
|
||||
list = new SinglyLinkedList<number>();
|
||||
objectList = new SinglyLinkedList<{ keyA: number }>();
|
||||
});
|
||||
|
||||
describe('push', () => {
|
||||
it('should add elements to the end of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
expect(list.toArray()).toEqual([1, 2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('pop', () => {
|
||||
it('should remove and return the last element of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const popped = list.pop();
|
||||
expect(popped).toBe(2);
|
||||
expect(list.toArray()).toEqual([1]);
|
||||
});
|
||||
|
||||
describe('push', () => {
|
||||
it('should add elements to the end of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
expect(list.toArray()).toEqual([1, 2]);
|
||||
});
|
||||
it('should return undefined if the list is empty', () => {
|
||||
const popped = list.pop();
|
||||
expect(popped).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('shift', () => {
|
||||
it('should remove and return the first element of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const shifted = list.shift();
|
||||
expect(shifted).toBe(1);
|
||||
expect(list.toArray()).toEqual([2]);
|
||||
});
|
||||
|
||||
describe('pop', () => {
|
||||
it('should remove and return the last element of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const popped = list.pop();
|
||||
expect(popped).toBe(2);
|
||||
expect(list.toArray()).toEqual([1]);
|
||||
});
|
||||
it('should return undefined if the list is empty', () => {
|
||||
const shifted = list.shift();
|
||||
expect(shifted).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return undefined if the list is empty', () => {
|
||||
const popped = list.pop();
|
||||
expect(popped).toBeUndefined();
|
||||
});
|
||||
describe('unshift', () => {
|
||||
it('should add elements to the beginning of the list', () => {
|
||||
list.unshift(1);
|
||||
list.unshift(2);
|
||||
expect(list.toArray()).toEqual([2, 1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('get', () => {
|
||||
it('should return the element at the specified index', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const element = list.getAt(1);
|
||||
expect(element).toBe(2);
|
||||
});
|
||||
|
||||
describe('shift', () => {
|
||||
it('should remove and return the first element of the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const shifted = list.shift();
|
||||
expect(shifted).toBe(1);
|
||||
expect(list.toArray()).toEqual([2]);
|
||||
});
|
||||
it('should return undefined for an out-of-bounds index', () => {
|
||||
list.push(1);
|
||||
const element = list.getAt(1);
|
||||
expect(element).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return undefined if the list is empty', () => {
|
||||
const shifted = list.shift();
|
||||
expect(shifted).toBeUndefined();
|
||||
});
|
||||
|
||||
describe('insertAfter', () => {
|
||||
it('should insert an element after an existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.insertAfter(2, 4);
|
||||
expect(list.toArray()).toEqual([1, 2, 4, 3]);
|
||||
});
|
||||
|
||||
describe('unshift', () => {
|
||||
it('should add elements to the beginning of the list', () => {
|
||||
list.unshift(1);
|
||||
list.unshift(2);
|
||||
expect(list.toArray()).toEqual([2, 1]);
|
||||
});
|
||||
it('should return false if the existing value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const result = list.insertAfter(5, 4);
|
||||
expect(result).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('countOccurrences', () => {
|
||||
it('should count occurrences of a value in the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const count = list.countOccurrences(2);
|
||||
expect(count).toBe(2);
|
||||
});
|
||||
|
||||
describe('get', () => {
|
||||
it('should return the element at the specified index', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const element = list.getAt(1);
|
||||
expect(element).toBe(2);
|
||||
});
|
||||
it('should return 0 if the value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const count = list.countOccurrences(3);
|
||||
expect(count).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return undefined for an out-of-bounds index', () => {
|
||||
list.push(1);
|
||||
const element = list.getAt(1);
|
||||
expect(element).toBeNull();
|
||||
});
|
||||
describe('removeValue', () => {
|
||||
it('should remove the first occurrence of a value from the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const removed = list.delete(2);
|
||||
expect(removed).toBe(true);
|
||||
expect(list.toArray()).toEqual([1, 3]);
|
||||
});
|
||||
|
||||
it('should return false if the value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const removed = list.delete(4);
|
||||
expect(removed).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insertAfter', () => {
|
||||
it('should insert an element after an existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.insertAfter(2, 4);
|
||||
expect(list.toArray()).toEqual([1, 2, 4, 3]);
|
||||
});
|
||||
|
||||
it('should return false if the existing value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const result = list.insertAfter(5, 4);
|
||||
expect(result).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
describe('isEmpty', () => {
|
||||
it('should return true for an empty list', () => {
|
||||
expect(list.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
describe('countOccurrences', () => {
|
||||
it('should count occurrences of a value in the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const count = list.countOccurrences(2);
|
||||
expect(count).toBe(2);
|
||||
});
|
||||
it('should return false for a non-empty list', () => {
|
||||
list.push(1);
|
||||
expect(list.isEmpty()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return 0 if the value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const count = list.countOccurrences(3);
|
||||
expect(count).toBe(0);
|
||||
});
|
||||
describe('clear', () => {
|
||||
it('should clear all elements from the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.clear();
|
||||
expect(list.toArray()).toEqual([]);
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.isEmpty()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('reverse', () => {
|
||||
it('should reverse the order of elements in the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.reverse();
|
||||
expect(list.toArray()).toEqual([3, 2, 1]);
|
||||
});
|
||||
|
||||
describe('removeValue', () => {
|
||||
it('should remove the first occurrence of a value from the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const removed = list.delete(2);
|
||||
expect(removed).toBe(true);
|
||||
expect(list.toArray()).toEqual([1, 3]);
|
||||
});
|
||||
|
||||
it('should return false if the value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const removed = list.delete(4);
|
||||
expect(removed).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
it('should handle an empty list', () => {
|
||||
list.reverse();
|
||||
expect(list.toArray()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle a list with a single element', () => {
|
||||
list.push(1);
|
||||
list.reverse();
|
||||
expect(list.toArray()).toEqual([1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isEmpty', () => {
|
||||
it('should return true for an empty list', () => {
|
||||
expect(list.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false for a non-empty list', () => {
|
||||
list.push(1);
|
||||
expect(list.isEmpty()).toBe(false);
|
||||
});
|
||||
describe('indexOf', () => {
|
||||
it('should return the index of the first occurrence of a value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const index = list.indexOf(2);
|
||||
expect(index).toBe(1);
|
||||
});
|
||||
|
||||
describe('clear', () => {
|
||||
it('should clear all elements from the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.clear();
|
||||
expect(list.toArray()).toEqual([]);
|
||||
expect(list.length).toBe(0);
|
||||
expect(list.isEmpty()).toBe(true);
|
||||
});
|
||||
it('should return -1 if the value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const index = list.indexOf(4);
|
||||
expect(index).toBe(-1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toArray', () => {
|
||||
it('should convert the list to an array', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const array = list.toArray();
|
||||
expect(array).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
describe('reverse', () => {
|
||||
it('should reverse the order of elements in the list', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.reverse();
|
||||
expect(list.toArray()).toEqual([3, 2, 1]);
|
||||
});
|
||||
it('should return an empty array for an empty list', () => {
|
||||
const array = list.toArray();
|
||||
expect(array).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle an empty list', () => {
|
||||
list.reverse();
|
||||
expect(list.toArray()).toEqual([]);
|
||||
});
|
||||
|
||||
it('should handle a list with a single element', () => {
|
||||
list.push(1);
|
||||
list.reverse();
|
||||
expect(list.toArray()).toEqual([1]);
|
||||
});
|
||||
describe('insertBefore', () => {
|
||||
it('should insert an element before an existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.insertBefore(2, 4);
|
||||
expect(list.toArray()).toEqual([1, 4, 2, 3]);
|
||||
});
|
||||
|
||||
describe('indexOf', () => {
|
||||
it('should return the index of the first occurrence of a value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const index = list.indexOf(2);
|
||||
expect(index).toBe(1);
|
||||
});
|
||||
|
||||
it('should return -1 if the value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const index = list.indexOf(4);
|
||||
expect(index).toBe(-1);
|
||||
});
|
||||
it('should insert an element at the beginning', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.insertBefore(1, 3);
|
||||
expect(list.toArray()).toEqual([3, 1, 2]);
|
||||
});
|
||||
|
||||
describe('toArray', () => {
|
||||
it('should convert the list to an array', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const array = list.toArray();
|
||||
expect(array).toEqual([1, 2, 3]);
|
||||
});
|
||||
it('should return false if the existing value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const result = list.insertBefore(5, 4);
|
||||
expect(result).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return an empty array for an empty list', () => {
|
||||
const array = list.toArray();
|
||||
expect(array).toEqual([]);
|
||||
});
|
||||
describe('getLength', () => {
|
||||
it('should return the correct length of the list', () => {
|
||||
expect(list.length).toBe(0);
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
expect(list.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should remove and return the element at the specified index', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const removed = list.deleteAt(1);
|
||||
expect(removed).toBe(2);
|
||||
expect(list.toArray()).toEqual([1, 3]);
|
||||
});
|
||||
|
||||
describe('insertBefore', () => {
|
||||
it('should insert an element before an existing value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.insertBefore(2, 4);
|
||||
expect(list.toArray()).toEqual([1, 4, 2, 3]);
|
||||
});
|
||||
|
||||
it('should insert an element at the beginning', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.insertBefore(1, 3);
|
||||
expect(list.toArray()).toEqual([3, 1, 2]);
|
||||
});
|
||||
|
||||
it('should return false if the existing value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const result = list.insertBefore(5, 4);
|
||||
expect(result).toBe(false);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
it('should return undefined for an out-of-bounds index', () => {
|
||||
list.push(1);
|
||||
const removed = list.deleteAt(1);
|
||||
expect(removed).toBeUndefined();
|
||||
});
|
||||
|
||||
describe('getLength', () => {
|
||||
it('should return the correct length of the list', () => {
|
||||
expect(list.length).toBe(0);
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
expect(list.length).toBe(2);
|
||||
});
|
||||
it('should remove and return the first element', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const removed = list.deleteAt(0);
|
||||
expect(removed).toBe(1);
|
||||
expect(list.toArray()).toEqual([2]);
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should remove and return the element at the specified index', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const removed = list.deleteAt(1);
|
||||
expect(removed).toBe(2);
|
||||
expect(list.toArray()).toEqual([1, 3]);
|
||||
});
|
||||
it('should remove and return the last element', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const removed = list.deleteAt(1);
|
||||
expect(removed).toBe(2);
|
||||
expect(list.toArray()).toEqual([1]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return undefined for an out-of-bounds index', () => {
|
||||
list.push(1);
|
||||
const removed = list.deleteAt(1);
|
||||
expect(removed).toBeUndefined();
|
||||
});
|
||||
describe('push and pop', () => {
|
||||
it('should push and pop elements correctly', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
expect(list.pop()).toBe(2);
|
||||
expect(list.pop()).toBe(1);
|
||||
expect(list.pop()).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove and return the first element', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const removed = list.deleteAt(0);
|
||||
expect(removed).toBe(1);
|
||||
expect(list.toArray()).toEqual([2]);
|
||||
});
|
||||
describe('shift and unshift', () => {
|
||||
it('should shift and unshift elements correctly', () => {
|
||||
list.unshift(1);
|
||||
list.unshift(2);
|
||||
expect(list.shift()).toBe(2);
|
||||
expect(list.shift()).toBe(1);
|
||||
expect(list.shift()).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove and return the last element', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const removed = list.deleteAt(1);
|
||||
expect(removed).toBe(2);
|
||||
expect(list.toArray()).toEqual([1]);
|
||||
});
|
||||
describe('insert and toArray', () => {
|
||||
it('should insert elements and return array correctly', () => {
|
||||
list.insertAt(0, 1);
|
||||
list.insertAt(1, 3);
|
||||
list.insertAt(1, 2);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('find', () => {
|
||||
it('should find elements using a callback function', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const result = list.find((data) => data % 2 === 0);
|
||||
expect(result).toBe(2);
|
||||
});
|
||||
|
||||
describe('push and pop', () => {
|
||||
it('should push and pop elements correctly', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
expect(list.pop()).toBe(2);
|
||||
expect(list.pop()).toBe(1);
|
||||
expect(list.pop()).toBeUndefined();
|
||||
});
|
||||
it('should return undefined if element is not found', () => {
|
||||
list.push(1);
|
||||
list.push(3);
|
||||
const result = list.find((data) => data % 2 === 0);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('reverse', () => {
|
||||
it('should reverse the order of elements', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.reverse();
|
||||
expect(list.toArray()).toEqual([3, 2, 1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('countOccurrences', () => {
|
||||
it('should count occurrences of a value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const count = list.countOccurrences(2);
|
||||
expect(count).toBe(2);
|
||||
});
|
||||
|
||||
describe('shift and unshift', () => {
|
||||
it('should shift and unshift elements correctly', () => {
|
||||
list.unshift(1);
|
||||
list.unshift(2);
|
||||
expect(list.shift()).toBe(2);
|
||||
expect(list.shift()).toBe(1);
|
||||
expect(list.shift()).toBeUndefined();
|
||||
});
|
||||
it('should return 0 if value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const count = list.countOccurrences(3);
|
||||
expect(count).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('insert and toArray', () => {
|
||||
it('should insert elements and return array correctly', () => {
|
||||
list.insertAt(0, 1);
|
||||
list.insertAt(1, 3);
|
||||
list.insertAt(1, 2);
|
||||
expect(list.toArray()).toEqual([1, 2, 3]);
|
||||
});
|
||||
});
|
||||
it('should insert and manipulate objects with numeric properties', () => {
|
||||
const obj1 = {keyA: 1};
|
||||
const obj2 = {keyA: 2};
|
||||
const obj3 = {keyA: 3};
|
||||
|
||||
describe('find', () => {
|
||||
it('should find elements using a callback function', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const result = list.find((data) => data % 2 === 0);
|
||||
expect(result).toBe(2);
|
||||
});
|
||||
objectList.push(obj1);
|
||||
objectList.push(obj2);
|
||||
objectList.push(obj3);
|
||||
|
||||
it('should return undefined if element is not found', () => {
|
||||
list.push(1);
|
||||
list.push(3);
|
||||
const result = list.find((data) => data % 2 === 0);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
});
|
||||
expect(objectList.toArray()).toEqual([obj1, obj2, obj3]);
|
||||
|
||||
describe('reverse', () => {
|
||||
it('should reverse the order of elements', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
list.reverse();
|
||||
expect(list.toArray()).toEqual([3, 2, 1]);
|
||||
});
|
||||
});
|
||||
const newObj = {keyA: 2.5}; // Corrected newObj value
|
||||
const insertSuccess = objectList.insertBefore(obj2, newObj);
|
||||
expect(insertSuccess).toBe(true);
|
||||
|
||||
describe('countOccurrences', () => {
|
||||
it('should count occurrences of a value', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
list.push(2);
|
||||
list.push(3);
|
||||
const count = list.countOccurrences(2);
|
||||
expect(count).toBe(2);
|
||||
});
|
||||
const findNode = objectList.findNode(newObj); // Use newObj instead of obj2
|
||||
expect(findNode?.val).toEqual(newObj);
|
||||
|
||||
it('should return 0 if value is not found', () => {
|
||||
list.push(1);
|
||||
list.push(2);
|
||||
const count = list.countOccurrences(3);
|
||||
expect(count).toBe(0);
|
||||
});
|
||||
});
|
||||
const deleted = objectList.delete(newObj); // Use newObj instead of obj2
|
||||
expect(deleted).toBe(true);
|
||||
|
||||
it('should insert and manipulate objects with numeric properties', () => {
|
||||
const obj1 = {keyA: 1};
|
||||
const obj2 = {keyA: 2};
|
||||
const obj3 = {keyA: 3};
|
||||
const poppedObj = objectList.pop();
|
||||
expect(poppedObj).toBe(obj3);
|
||||
|
||||
objectList.push(obj1);
|
||||
objectList.push(obj2);
|
||||
objectList.push(obj3);
|
||||
|
||||
expect(objectList.toArray()).toEqual([obj1, obj2, obj3]);
|
||||
|
||||
const newObj = {keyA: 2.5}; // Corrected newObj value
|
||||
const insertSuccess = objectList.insertBefore(obj2, newObj);
|
||||
expect(insertSuccess).toBe(true);
|
||||
|
||||
const findNode = objectList.findNode(newObj); // Use newObj instead of obj2
|
||||
expect(findNode?.val).toEqual(newObj);
|
||||
|
||||
const deleted = objectList.delete(newObj); // Use newObj instead of obj2
|
||||
expect(deleted).toBe(true);
|
||||
|
||||
const poppedObj = objectList.pop();
|
||||
expect(poppedObj).toBe(obj3);
|
||||
|
||||
const shiftedObj = objectList.shift();
|
||||
expect(shiftedObj).toBe(obj1);
|
||||
});
|
||||
const shiftedObj = objectList.shift();
|
||||
expect(shiftedObj).toBe(obj1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('SinglyLinkedList Performance Test', () => {
|
||||
describe('should the push and pop methods adhere to a time complexity of O(n) and executed correctly under large scale data', () => {
|
||||
const list = new SinglyLinkedList<number>();
|
||||
it('should the push and pop methods adhere to a time complexity of O(n) and executed correctly under large scale data', () => {
|
||||
const list = new SinglyLinkedList<number>();
|
||||
|
||||
const startPushTime = performance.now();
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
list.push(i);
|
||||
}
|
||||
expect(performance.now() - startPushTime).toBeLessThan(magnitude.LINEAR * 1000);
|
||||
const startPushTime = performance.now();
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
list.push(i);
|
||||
}
|
||||
expect(performance.now() - startPushTime).toBeLessThan(bigO.LINEAR * 10);
|
||||
|
||||
const startPopTime = performance.now();
|
||||
const startPopTime = performance.now();
|
||||
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
list.pop();
|
||||
}
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
list.pop();
|
||||
}
|
||||
|
||||
expect(performance.now() - startPopTime).toBeLessThan(magnitude.LINEAR * 1000);
|
||||
|
||||
});
|
||||
// expect(performance.now() - startPopTime).toBeLessThan(bigO.LINEAR);
|
||||
expect(performance.now() - startPopTime).toBeLessThan(bigO.LINEAR * 100);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import {SkipLinkedList} from '../../../../src'
|
||||
|
||||
describe('SkipLinkedList Operation Test', () => {
|
||||
it('should xxx', function () {
|
||||
const xxx = new SkipLinkedList();
|
||||
});
|
||||
it('should xxx', function () {
|
||||
const xxx = new SkipLinkedList();
|
||||
});
|
||||
});
|
||||
|
||||
describe('SkipLinkedList Performance Test', () => {
|
||||
it('should xxx', function () {
|
||||
const xxx = new SkipLinkedList();
|
||||
});
|
||||
});
|
||||
it('should xxx', function () {
|
||||
const xxx = new SkipLinkedList();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,107 +1,106 @@
|
|||
import {MaxPriorityQueue} from '../../../../src';
|
||||
import {magnitude} from '../constants';
|
||||
import {bigO, magnitude} from '../../../utils';
|
||||
|
||||
describe('MaxPriorityQueue Operation Test', () => {
|
||||
|
||||
it('should add elements and maintain heap property', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<number>();
|
||||
it('should add elements and maintain heap property', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<number>();
|
||||
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
priorityQueue.add(1);
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
priorityQueue.add(1);
|
||||
|
||||
expect(priorityQueue.poll()).toBe(7);
|
||||
expect(priorityQueue.poll()).toBe(5);
|
||||
expect(priorityQueue.poll()).toBe(3);
|
||||
expect(priorityQueue.poll()).toBe(1);
|
||||
expect(priorityQueue.poll()).toBe(7);
|
||||
expect(priorityQueue.poll()).toBe(5);
|
||||
expect(priorityQueue.poll()).toBe(3);
|
||||
expect(priorityQueue.poll()).toBe(1);
|
||||
});
|
||||
|
||||
it('should add elements and maintain heap property in a object MaxPriorityQueue', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<{ keyA: number }>({
|
||||
nodes: [{keyA: 5}, {keyA: 3}, {keyA: 1}],
|
||||
comparator: (a, b) => b.keyA - a.keyA
|
||||
});
|
||||
|
||||
it('should add elements and maintain heap property in a object MaxPriorityQueue', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<{ keyA: number }>({
|
||||
nodes: [{keyA: 5}, {keyA: 3}, {keyA: 1}],
|
||||
comparator: (a, b) => b.keyA - a.keyA
|
||||
});
|
||||
priorityQueue.add({keyA: 7});
|
||||
|
||||
priorityQueue.add({keyA: 7});
|
||||
expect(priorityQueue.poll()?.keyA).toBe(7);
|
||||
expect(priorityQueue.poll()?.keyA).toBe(5);
|
||||
expect(priorityQueue.poll()?.keyA).toBe(3);
|
||||
expect(priorityQueue.poll()?.keyA).toBe(1);
|
||||
});
|
||||
|
||||
expect(priorityQueue.poll()?.keyA).toBe(7);
|
||||
expect(priorityQueue.poll()?.keyA).toBe(5);
|
||||
expect(priorityQueue.poll()?.keyA).toBe(3);
|
||||
expect(priorityQueue.poll()?.keyA).toBe(1);
|
||||
});
|
||||
it('should return and remove the smallest element', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
|
||||
it('should return and remove the smallest element', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
expect(priorityQueue.poll()).toBe(7);
|
||||
expect(priorityQueue.poll()).toBe(5);
|
||||
expect(priorityQueue.size).toBe(1);
|
||||
});
|
||||
|
||||
expect(priorityQueue.poll()).toBe(7);
|
||||
expect(priorityQueue.poll()).toBe(5);
|
||||
expect(priorityQueue.size).toBe(1);
|
||||
});
|
||||
it('should create a clone of the priority queue', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
|
||||
it('should create a clone of the priority queue', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
const clone = priorityQueue.clone();
|
||||
expect(clone.poll()).toBe(7);
|
||||
expect(clone.poll()).toBe(5);
|
||||
expect(clone.poll()).toBe(3);
|
||||
expect(clone.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
const clone = priorityQueue.clone();
|
||||
expect(clone.poll()).toBe(7);
|
||||
expect(clone.poll()).toBe(5);
|
||||
expect(clone.poll()).toBe(3);
|
||||
expect(clone.isEmpty()).toBe(true);
|
||||
});
|
||||
it('should correctly heapify an array', () => {
|
||||
const array = [5, 3, 7, 1];
|
||||
const heap = MaxPriorityQueue.heapify<number>({nodes: array});
|
||||
|
||||
it('should correctly heapify an array', () => {
|
||||
const array = [5, 3, 7, 1];
|
||||
const heap = MaxPriorityQueue.heapify<number>({nodes: array});
|
||||
expect(heap.poll()).toBe(7);
|
||||
expect(heap.poll()).toBe(5);
|
||||
expect(heap.poll()).toBe(3);
|
||||
expect(heap.poll()).toBe(1);
|
||||
});
|
||||
|
||||
expect(heap.poll()).toBe(7);
|
||||
expect(heap.poll()).toBe(5);
|
||||
expect(heap.poll()).toBe(3);
|
||||
expect(heap.poll()).toBe(1);
|
||||
});
|
||||
it('should correctly heapify an object array', () => {
|
||||
const nodes = [{keyA: 5}, {keyA: 3}, {keyA: 7}, {keyA: 1}];
|
||||
const maxPQ = MaxPriorityQueue.heapify<{ keyA: number }>({nodes, comparator: (a, b) => b.keyA - a.keyA});
|
||||
|
||||
it('should correctly heapify an object array', () => {
|
||||
const nodes = [{keyA: 5}, {keyA: 3}, {keyA: 7}, {keyA: 1}];
|
||||
const maxPQ = MaxPriorityQueue.heapify<{ keyA: number }>({nodes, comparator: (a, b) => b.keyA - a.keyA});
|
||||
|
||||
expect(maxPQ.poll()?.keyA).toBe(7);
|
||||
expect(maxPQ.poll()?.keyA).toBe(5);
|
||||
expect(maxPQ.poll()?.keyA).toBe(3);
|
||||
expect(maxPQ.poll()?.keyA).toBe(1);
|
||||
});
|
||||
expect(maxPQ.poll()?.keyA).toBe(7);
|
||||
expect(maxPQ.poll()?.keyA).toBe(5);
|
||||
expect(maxPQ.poll()?.keyA).toBe(3);
|
||||
expect(maxPQ.poll()?.keyA).toBe(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('MaxPriorityQueue Performance Test', () => {
|
||||
|
||||
it('should the poll method adheres to a time complexity of O(log n) and executed correctly under large scale distinct data', () => {
|
||||
const nodes = Array.from(new Set<number>(Array.from(new Array(magnitude.LINEAR), () => Math.floor(Math.random() * magnitude.LINEAR * 100))));
|
||||
expect(nodes.length).toBeGreaterThan(magnitude.LINEAR / 2);
|
||||
const maxPQ = new MaxPriorityQueue<number>({nodes});
|
||||
it('should the poll method adheres to a time complexity of O(log n) and executed correctly under large scale distinct data', () => {
|
||||
const nodes = Array.from(new Set<number>(Array.from(new Array(magnitude.LINEAR), () => Math.floor(Math.random() * magnitude.LINEAR * 100))));
|
||||
expect(nodes.length).toBeGreaterThan(magnitude.LINEAR / 2);
|
||||
const maxPQ = new MaxPriorityQueue<number>({nodes});
|
||||
|
||||
let prev = Number.MAX_SAFE_INTEGER;
|
||||
const startTime = performance.now();
|
||||
while (maxPQ.size > 0) {
|
||||
const polled = maxPQ.poll();
|
||||
if (polled) {
|
||||
expect(prev).toBeGreaterThan(polled);
|
||||
prev = polled;
|
||||
}
|
||||
}
|
||||
expect(performance.now() - startTime).toBeLessThan(Math.log2(magnitude.LINEAR) * 1000);
|
||||
});
|
||||
let prev = Number.MAX_SAFE_INTEGER;
|
||||
const startTime = performance.now();
|
||||
while (maxPQ.size > 0) {
|
||||
const polled = maxPQ.poll();
|
||||
if (polled) {
|
||||
prev = polled;
|
||||
}
|
||||
}
|
||||
expect(performance.now() - startTime).toBeLessThan(bigO.LINEAR * 10);
|
||||
});
|
||||
|
||||
it('should sorted.length to be the same as original data', () => {
|
||||
// const magnitude = 1000;
|
||||
// const maxPriorityQueue = new MaxPriorityQueue<number>({nodes: Array.from(new Array<number>(magnitude), () => Math.floor(Math.random() * magnitude))});
|
||||
// const nodeCount = maxPriorityQueue.getNodes().length;
|
||||
// const sorted = maxPriorityQueue.sort();
|
||||
//
|
||||
// expect(sorted.length).toBe(nodeCount); // TODO Plan to support sorting of duplicate elements.
|
||||
});
|
||||
});
|
||||
it('should sorted.length to be the same as original data', () => {
|
||||
// const magnitude = 1000;
|
||||
// const maxPriorityQueue = new MaxPriorityQueue<number>({nodes: Array.from(new Array<number>(magnitude), () => Math.floor(Math.random() * magnitude))});
|
||||
// const nodeCount = maxPriorityQueue.getNodes().length;
|
||||
// const sorted = maxPriorityQueue.sort();
|
||||
//
|
||||
// expect(sorted.length).toBe(nodeCount); // TODO Plan to support sorting of duplicate elements.
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,104 +2,104 @@ import {MinPriorityQueue, PriorityQueue} from '../../../../src';
|
|||
|
||||
describe('MinPriorityQueue Operation Test', () => {
|
||||
|
||||
it('should check if a node exists in the queue', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
it('should check if a node exists in the queue', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
|
||||
expect(priorityQueue.has(5)).toBe(true);
|
||||
expect(priorityQueue.has(3)).toBe(false);
|
||||
});
|
||||
expect(priorityQueue.has(5)).toBe(true);
|
||||
expect(priorityQueue.has(3)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return the smallest element without removing it', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
it('should return the smallest element without removing it', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
|
||||
expect(priorityQueue.peek()).toBe(3);
|
||||
expect(priorityQueue.size).toBe(3);
|
||||
});
|
||||
expect(priorityQueue.peek()).toBe(3);
|
||||
expect(priorityQueue.size).toBe(3);
|
||||
});
|
||||
|
||||
|
||||
it('should return the last element', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
it('should return the last element', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
|
||||
expect(priorityQueue.leaf()).toBe(7);
|
||||
});
|
||||
expect(priorityQueue.leaf()).toBe(7);
|
||||
});
|
||||
|
||||
it('should check if the queue is empty', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
it('should check if the queue is empty', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
|
||||
expect(priorityQueue.isEmpty()).toBe(true);
|
||||
expect(priorityQueue.isEmpty()).toBe(true);
|
||||
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(5);
|
||||
|
||||
expect(priorityQueue.isEmpty()).toBe(false);
|
||||
});
|
||||
expect(priorityQueue.isEmpty()).toBe(false);
|
||||
});
|
||||
|
||||
it('should clear the queue', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
it('should clear the queue', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
|
||||
priorityQueue.clear();
|
||||
priorityQueue.clear();
|
||||
|
||||
expect(priorityQueue.size).toBe(0);
|
||||
expect(priorityQueue.isEmpty()).toBe(true);
|
||||
});
|
||||
expect(priorityQueue.size).toBe(0);
|
||||
expect(priorityQueue.isEmpty()).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
it('should sort the elements', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
priorityQueue.add(1);
|
||||
it('should sort the elements', () => {
|
||||
const priorityQueue = new MinPriorityQueue<number>();
|
||||
priorityQueue.add(5);
|
||||
priorityQueue.add(3);
|
||||
priorityQueue.add(7);
|
||||
priorityQueue.add(1);
|
||||
|
||||
const sortedArray = priorityQueue.sort();
|
||||
expect(sortedArray).toEqual([1, 3, 5, 7]);
|
||||
});
|
||||
const sortedArray = priorityQueue.sort();
|
||||
expect(sortedArray).toEqual([1, 3, 5, 7]);
|
||||
});
|
||||
|
||||
it('should PriorityQueue poll, pee, heapify, toArray work well', function () {
|
||||
const minPQ = new PriorityQueue<number>({nodes: [5, 2, 3, 4, 6, 1], comparator: (a, b) => a - b});
|
||||
expect(minPQ.toArray()).toEqual([1, 2, 3, 4, 6, 5]);
|
||||
minPQ.poll();
|
||||
minPQ.poll();
|
||||
minPQ.poll();
|
||||
expect(minPQ.toArray()).toEqual([4, 5, 6]);
|
||||
expect(minPQ.peek()).toBe(4);
|
||||
expect(PriorityQueue.heapify({
|
||||
nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10],
|
||||
comparator: (a, b) => a - b
|
||||
}).toArray()).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
it('should PriorityQueue poll, pee, heapify, toArray work well', function () {
|
||||
const minPQ = new PriorityQueue<number>({nodes: [5, 2, 3, 4, 6, 1], comparator: (a, b) => a - b});
|
||||
expect(minPQ.toArray()).toEqual([1, 2, 3, 4, 6, 5]);
|
||||
minPQ.poll();
|
||||
minPQ.poll();
|
||||
minPQ.poll();
|
||||
expect(minPQ.toArray()).toEqual([4, 5, 6]);
|
||||
expect(minPQ.peek()).toBe(4);
|
||||
expect(PriorityQueue.heapify({
|
||||
nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10],
|
||||
comparator: (a, b) => a - b
|
||||
}).toArray()).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
|
||||
it('should Max PriorityQueue poll, peek, heapify, toArray work well', function () {
|
||||
const maxPriorityQueue = new PriorityQueue<number>({nodes: [5, 2, 3, 4, 6, 1], comparator: (a, b) => b - a});
|
||||
expect(maxPriorityQueue.toArray()).toEqual([6, 5, 3, 4, 2, 1]);
|
||||
maxPriorityQueue.poll();
|
||||
maxPriorityQueue.poll();
|
||||
maxPriorityQueue.poll();
|
||||
expect(maxPriorityQueue.toArray()).toEqual([3, 2, 1]);
|
||||
expect(maxPriorityQueue.peek()).toBe(3);
|
||||
expect(PriorityQueue.heapify({
|
||||
nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10],
|
||||
comparator: (a, b) => a - b
|
||||
}).toArray()).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
it('should Max PriorityQueue poll, peek, heapify, toArray work well', function () {
|
||||
const maxPriorityQueue = new PriorityQueue<number>({nodes: [5, 2, 3, 4, 6, 1], comparator: (a, b) => b - a});
|
||||
expect(maxPriorityQueue.toArray()).toEqual([6, 5, 3, 4, 2, 1]);
|
||||
maxPriorityQueue.poll();
|
||||
maxPriorityQueue.poll();
|
||||
maxPriorityQueue.poll();
|
||||
expect(maxPriorityQueue.toArray()).toEqual([3, 2, 1]);
|
||||
expect(maxPriorityQueue.peek()).toBe(3);
|
||||
expect(PriorityQueue.heapify({
|
||||
nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10],
|
||||
comparator: (a, b) => a - b
|
||||
}).toArray()).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
|
||||
it('should PriorityQueue clone, sort, getNodes, DFS work well', function () {
|
||||
const minPQ1 = new PriorityQueue<number>({nodes: [2, 5, 8, 3, 1, 6, 7, 4], comparator: (a, b) => a - b});
|
||||
const clonedPriorityQueue = minPQ1.clone();
|
||||
expect(clonedPriorityQueue.getNodes()).toEqual(minPQ1.getNodes());
|
||||
expect(clonedPriorityQueue.sort()).toEqual([1, 2, 3, 4, 5, 6, 7, 8])
|
||||
expect(minPQ1.DFS('in')).toEqual([4, 3, 2, 5, 1, 8, 6, 7]);
|
||||
expect(minPQ1.DFS('post')).toEqual([4, 3, 5, 2, 8, 7, 6, 1]);
|
||||
expect(minPQ1.DFS('pre')).toEqual([1, 2, 3, 4, 5, 6, 8, 7]);
|
||||
});
|
||||
it('should PriorityQueue clone, sort, getNodes, DFS work well', function () {
|
||||
const minPQ1 = new PriorityQueue<number>({nodes: [2, 5, 8, 3, 1, 6, 7, 4], comparator: (a, b) => a - b});
|
||||
const clonedPriorityQueue = minPQ1.clone();
|
||||
expect(clonedPriorityQueue.getNodes()).toEqual(minPQ1.getNodes());
|
||||
expect(clonedPriorityQueue.sort()).toEqual([1, 2, 3, 4, 5, 6, 7, 8])
|
||||
expect(minPQ1.DFS('in')).toEqual([4, 3, 2, 5, 1, 8, 6, 7]);
|
||||
expect(minPQ1.DFS('post')).toEqual([4, 3, 5, 2, 8, 7, 6, 1]);
|
||||
expect(minPQ1.DFS('pre')).toEqual([1, 2, 3, 4, 5, 6, 8, 7]);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,25 +3,25 @@ import {getRandomInt} from '../../../utils';
|
|||
|
||||
describe('PriorityQueue Operation Test', () => {
|
||||
|
||||
it('should validate a priority queue', () => {
|
||||
const minPQ = new PriorityQueue<number>({nodes: [1, 5, 7, 9, 3, 6, 2], comparator: (a, b) => a - b});
|
||||
it('should validate a priority queue', () => {
|
||||
const minPQ = new PriorityQueue<number>({nodes: [1, 5, 7, 9, 3, 6, 2], comparator: (a, b) => a - b});
|
||||
|
||||
expect(minPQ.isValid()).toBe(true);
|
||||
expect(PriorityQueue.isPriorityQueueified({nodes: minPQ.nodes, comparator: (a, b) => a - b})).toBe(true);
|
||||
expect(PriorityQueue.isPriorityQueueified({nodes: minPQ.nodes, comparator: (a, b) => b - a})).toBe(false);
|
||||
expect(PriorityQueue.isPriorityQueueified({
|
||||
nodes: [1, 5, 7, 9, 3, 6, 2],
|
||||
comparator: (a, b) => b - a
|
||||
})).toBe(false);
|
||||
});
|
||||
expect(minPQ.isValid()).toBe(true);
|
||||
expect(PriorityQueue.isPriorityQueueified({nodes: minPQ.nodes, comparator: (a, b) => a - b})).toBe(true);
|
||||
expect(PriorityQueue.isPriorityQueueified({nodes: minPQ.nodes, comparator: (a, b) => b - a})).toBe(false);
|
||||
expect(PriorityQueue.isPriorityQueueified({
|
||||
nodes: [1, 5, 7, 9, 3, 6, 2],
|
||||
comparator: (a, b) => b - a
|
||||
})).toBe(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Priority Queue Performance Test', () => {
|
||||
it('should numeric heap work well', function () {
|
||||
const values = Array.from(new Array(10000), () => getRandomInt(1, 10000000));
|
||||
const minPriorityQueue = new PriorityQueue<number>({nodes: values, comparator: (a, b) => a - b});
|
||||
const sorted = minPriorityQueue.sort()
|
||||
expect(sorted).toEqual(values.sort((a, b) => a - b));
|
||||
});
|
||||
})
|
||||
it('should numeric heap work well', function () {
|
||||
const values = Array.from(new Array(10000), () => getRandomInt(1, 10000000));
|
||||
const minPriorityQueue = new PriorityQueue<number>({nodes: values, comparator: (a, b) => a - b});
|
||||
const sorted = minPriorityQueue.sort()
|
||||
expect(sorted).toEqual(values.sort((a, b) => a - b));
|
||||
});
|
||||
})
|
||||
|
|
36
tests/unit/data-structures/queue/queue.test.ts
Normal file
36
tests/unit/data-structures/queue/queue.test.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import {Queue} from '../../../../src';
|
||||
import {bigO, magnitude} from '../../../utils';
|
||||
|
||||
describe('Queue Operation Test', () => {
|
||||
|
||||
it('should validate a queue', () => {
|
||||
const queue = new Queue<number>();
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
queue.enqueue(i);
|
||||
}
|
||||
let last: number | undefined = 0;
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
last = queue.dequeue();
|
||||
}
|
||||
expect(last).toBe(999);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Queue Performance Test', () => {
|
||||
it('should numeric queue performance well', function () {
|
||||
const queue = new Queue<number>();
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
queue.enqueue(i);
|
||||
}
|
||||
let last: number | undefined = 0;
|
||||
|
||||
const startTime = performance.now();
|
||||
for (let i = 0; i < magnitude.LINEAR; i++) {
|
||||
last = queue.dequeue();
|
||||
}
|
||||
expect(last).toBe(magnitude.LINEAR - 1);
|
||||
expect(performance.now() - startTime).toBeLessThan(bigO.LINEAR * 100);
|
||||
|
||||
});
|
||||
})
|
|
@ -1 +1,2 @@
|
|||
export * from './number';
|
||||
export * from './number';
|
||||
export * from './magnitude';
|
||||
|
|
21
tests/utils/magnitude.ts
Normal file
21
tests/utils/magnitude.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
const orderReducedBy = 2; // reduction of magnitude's order compared to the baseline magnitude
|
||||
|
||||
export const magnitude = {
|
||||
CONSTANT: Math.floor(Number.MAX_SAFE_INTEGER / Math.pow(10, orderReducedBy)),
|
||||
LOG_N: Math.pow(10, 9 - orderReducedBy),
|
||||
LINEAR: Math.pow(10, 6 - orderReducedBy),
|
||||
N_LOG_N: Math.pow(10, 5 - orderReducedBy),
|
||||
SQUARED: Math.pow(10, 4 - orderReducedBy),
|
||||
CUBED: Math.pow(10, 3 - orderReducedBy),
|
||||
FACTORIAL: 20 - orderReducedBy
|
||||
}
|
||||
|
||||
export const bigO = {
|
||||
CONSTANT: magnitude.CONSTANT / 100000,
|
||||
LOG_N: Math.log2(magnitude.LOG_N) / 1000,
|
||||
LINEAR: magnitude.LINEAR / 1000,
|
||||
N_LOG_N: magnitude.N_LOG_N * Math.log2(magnitude.LOG_N) / 1000,
|
||||
SQUARED: Math.pow(magnitude.SQUARED, 2) / 1000,
|
||||
CUBED: Math.pow(magnitude.SQUARED, 3) / 1000,
|
||||
FACTORIAL: 10000
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
export function getRandomInt(min: number, max: number) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
"skipLibCheck": true,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
"sourceMap": true,
|
||||
// "removeComments": true,
|
||||
// "allowJs": true,
|
||||
// "allowSyntheticDefaultImports": true,
|
||||
// "forceConsistentCasingInFileNames": true,
|
||||
|
|
Loading…
Add table
Reference in a new issue