Skip to content

Commit

Permalink
Refactor: The default callback function now supports returning values…
Browse files Browse the repository at this point in the history
… for null and undefined nodes with undefined keys. The deleteVertex method in AbstractGraph has been made abstract. Unnecessary magnitude variables have been removed from the magnitude function. fix: In directed and undirected graphs, the deleteVertex method now removes edges from adjacent nodes when deleting a vertex.
  • Loading branch information
zrwusa committed Dec 21, 2023
1 parent bbfa64f commit c3db558
Show file tree
Hide file tree
Showing 21 changed files with 286 additions and 227 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)

## [v1.49.2](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
## [v1.49.3](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)

### Changes

Expand Down
135 changes: 69 additions & 66 deletions README.md

Large diffs are not rendered by default.

91 changes: 43 additions & 48 deletions README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,51 @@ const {

## 代码片段

### 二叉搜索树 (BST) 代码示例
### 红黑树 代码示例

#### TS
```ts
import {RedBlackTree} from 'data-structure-typed';

const rbTree = new RedBlackTree<number>();
rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5])
rbTree.isAVLBalanced(); // true
rbTree.delete(10);
rbTree.isAVLBalanced(); // true
rbTree.print()
// ___6________
// / \
// ___4_ ___11________
// / \ / \
// _2_ 5 _8_ ____14__
// / \ / \ / \
// 1 3 7 9 12__ 15__
// \ \
// 13 16
```

#### JS
```js
import {RedBlackTree} from 'data-structure-typed';

const rbTree = new RedBlackTree();
rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5])
rbTree.isAVLBalanced(); // true
rbTree.delete(10);
rbTree.isAVLBalanced(); // true
rbTree.print()
// ___6________
// / \
// ___4_ ___11________
// / \ / \
// _2_ 5 _8_ ____14__
// / \ / \ / \
// 1 3 7 9 12__ 15__
// \ \
// 13 16
```

### 二叉搜索树 (BST) 代码示例

```ts
import {BST, BSTNode} from 'data-structure-typed';
Expand Down Expand Up @@ -262,31 +304,6 @@ objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], [
objBST.delete(11);
```

#### JS

```js
const {BST, BSTNode} = require('data-structure-typed');

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
bst.has(6); // true
const node6 = bst.getNode(6);
bst.getHeight(6) === 2; // true
bst.getHeight() === 5; // true
bst.getDepth(6) === 3; // true
const leftMost = bst.getLeftMost();
leftMost?.key === 1; // true

bst.delete(6);
bst.get(6); // undefined
bst.isAVLBalanced(); // true or false
const bfsIDs = bst.bfs();
bfsIDs[0] === 11; // true
```
### AVL树 代码示例

```ts
Expand All @@ -299,28 +316,6 @@ avlTree.delete(10);
avlTree.isAVLBalanced(); // true
```

### 红黑树 代码示例
```ts
import {RedBlackTree} from 'data-structure-typed';

const rbTree = new RedBlackTree<number>();
rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5])
rbTree.isAVLBalanced(); // true
rbTree.delete(10);
rbTree.isAVLBalanced(); // true
rbTree.print()
// ___6________
// / \
// ___4_ ___11________
// / \ / \
// _2_ 5 _8_ ____14__
// / \ / \ / \
// 1 3 7 9 12__ 15__
// \ \
// 13 16
```
### 有向图代码示例

```ts
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-structure-typed",
"version": "1.49.2",
"version": "1.49.3",
"description": "Data Structures of Javascript & TypeScript. Heap, Binary Tree, Red Black Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack. Benchmark compared with C++ STL. API aligned with ES6 and Java.util. Usability is comparable to Python",
"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",
Expand Down
2 changes: 1 addition & 1 deletion src/data-structures/binary-tree/binary-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1957,7 +1957,7 @@ export class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = Bi
}
}

protected _defaultOneParamCallback = (node: N) => node.key;
protected _defaultOneParamCallback = (node: N | null | undefined) => node ? node.key : undefined;

/**
* Swap the data of two nodes in the binary tree.
Expand Down
14 changes: 1 addition & 13 deletions src/data-structures/graph/abstract-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,19 +173,7 @@ export abstract class AbstractGraph<
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
*/

/**
* Time Complexity: O(1) - Constant time for Map operations.
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
*
* The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself.
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
* (`VertexKey`).
* @returns The method is returning a boolean value.
*/
deleteVertex(vertexOrKey: VO | VertexKey): boolean {
const vertexKey = this._getVertexKey(vertexOrKey);
return this._vertexMap.delete(vertexKey);
}
abstract deleteVertex(vertexOrKey: VO | VertexKey): boolean;

/**
* Time Complexity: O(K), where K is the number of vertexMap to be removed.
Expand Down
10 changes: 7 additions & 3 deletions src/data-structures/graph/directed-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export class DirectedGraph<
* (`VertexKey`).
* @returns The method is returning a boolean value.
*/
override deleteVertex(vertexOrKey: VO | VertexKey): boolean {
deleteVertex(vertexOrKey: VO | VertexKey): boolean {
let vertexKey: VertexKey;
let vertex: VO | undefined;
if (this.isVertexKey(vertexOrKey)) {
Expand All @@ -252,8 +252,12 @@ export class DirectedGraph<
}

if (vertex) {
this._outEdgeMap.delete(vertex)
this._inEdgeMap.delete(vertex)
const neighbors = this.getNeighbors(vertex);
for (const neighbor of neighbors) {
this._inEdgeMap.delete(neighbor);
}
this._outEdgeMap.delete(vertex);
this._inEdgeMap.delete(vertex);
}

return this._vertexMap.delete(vertexKey);
Expand Down
2 changes: 1 addition & 1 deletion src/data-structures/graph/undirected-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export class UndirectedGraph<
* (`VertexKey`).
* @returns The method is returning a boolean value.
*/
override deleteVertex(vertexOrKey: VO | VertexKey): boolean {
deleteVertex(vertexOrKey: VO | VertexKey): boolean {
let vertexKey: VertexKey;
let vertex: VO | undefined;
if (this.isVertexKey(vertexOrKey)) {
Expand Down
3 changes: 1 addition & 2 deletions src/data-structures/linked-list/singly-linked-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ export class SinglyLinkedList<E = any> extends IterableElementBase<E> {
this._tail = undefined;
this._size = 0;
if (elements) {
for (const el of elements)
this.push(el);
for (const el of elements) this.push(el);
}
}

Expand Down
24 changes: 12 additions & 12 deletions test/performance/data-structures/comparison/comparison.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { getRandomIntArray, magnitude } from '../../../utils';
import { isCompetitor } from '../../../config';

const suite = new Benchmark.Suite();
const { TEN_THOUSAND, HUNDRED_THOUSAND, LINEAR } = magnitude;
const { TEN_THOUSAND, HUNDRED_THOUSAND, MILLION } = magnitude;
const cOrderedMap = new OrderedMap<number, number>();
const arrHundredThousand = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);

Expand Down Expand Up @@ -96,10 +96,10 @@ if (isCompetitor) {
hm.getElementByKey(i);
}
})
.add(`CPT LL ${LINEAR.toLocaleString()} unshift`, () => {
.add(`CPT LL ${MILLION.toLocaleString()} unshift`, () => {
const list = new CLinkedList<number>();

for (let i = 0; i < LINEAR; i++) {
for (let i = 0; i < MILLION; i++) {
list.pushFront(i);
}
})
Expand All @@ -114,33 +114,33 @@ if (isCompetitor) {
pq.pop();
}
})
.add(`CPT DQ ${LINEAR.toLocaleString()} push`, () => {
.add(`CPT DQ ${MILLION.toLocaleString()} push`, () => {
const deque = new CDeque<number>();
for (let i = 0; i < LINEAR; i++) {
for (let i = 0; i < MILLION; i++) {
deque.pushBack(i);
}
})
.add(`CPT Q ${LINEAR.toLocaleString()} push`, () => {
.add(`CPT Q ${MILLION.toLocaleString()} push`, () => {
const queue = new CQueue<number>();

for (let i = 0; i < LINEAR; i++) {
for (let i = 0; i < MILLION; i++) {
queue.push(i);
}
})
.add(`CPT ST ${LINEAR.toLocaleString()} push`, () => {
.add(`CPT ST ${MILLION.toLocaleString()} push`, () => {
const queue = new CStack<number>();

for (let i = 0; i < LINEAR; i++) {
for (let i = 0; i < MILLION; i++) {
queue.push(i);
}
})
.add(`CPT ST ${LINEAR.toLocaleString()} push & pop`, () => {
.add(`CPT ST ${MILLION.toLocaleString()} push & pop`, () => {
const queue = new CStack<number>();

for (let i = 0; i < LINEAR; i++) {
for (let i = 0; i < MILLION; i++) {
queue.push(i);
}
for (let i = 0; i < LINEAR; i++) {
for (let i = 0; i < MILLION; i++) {
queue.pop();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,50 @@ import { magnitude } from '../../../utils';
import { isCompetitor } from '../../../config';

const suite = new Benchmark.Suite();
const { LINEAR } = magnitude;
const { MILLION } = magnitude;

suite.add(`${LINEAR.toLocaleString()} push`, () => {
suite.add(`${MILLION.toLocaleString()} push`, () => {
const list = new DoublyLinkedList<number>();

for (let i = 0; i < LINEAR; i++) {
list.push(i);
}
for (let i = 0; i < MILLION; i++) list.push(i);
});


if (isCompetitor) {
suite.add(`CPT ${LINEAR.toLocaleString()} push`, () => {
suite.add(`CPT ${MILLION.toLocaleString()} push`, () => {
const list = new CLinkedList<number>();

for (let i = 0; i < LINEAR; i++) {
list.pushBack(i);
}
for (let i = 0; i < MILLION; i++) list.pushBack(i);
});
}

suite.add(`${LINEAR.toLocaleString()} unshift`, () => {
suite.add(`${MILLION.toLocaleString()} unshift`, () => {
const list = new DoublyLinkedList<number>();

for (let i = 0; i < LINEAR; i++) {
list.unshift(i);
}
for (let i = 0; i < MILLION; i++) list.unshift(i);
});

if (isCompetitor) {
suite.add(`CPT ${LINEAR.toLocaleString()} unshift`, () => {
suite.add(`CPT ${MILLION.toLocaleString()} unshift`, () => {
const list = new CLinkedList<number>();

for (let i = 0; i < LINEAR; i++) {
list.pushFront(i);
}
for (let i = 0; i < MILLION; i++) list.pushFront(i);
});
}

suite
.add(`${LINEAR.toLocaleString()} unshift & shift`, () => {
.add(`${MILLION.toLocaleString()} unshift & shift`, () => {
const list = new DoublyLinkedList<number>();

for (let i = 0; i < LINEAR; i++) {
list.unshift(i);
}
for (let i = 0; i < LINEAR; i++) {
list.shift();
}
for (let i = 0; i < MILLION; i++) list.unshift(i);

for (let i = 0; i < MILLION; i++) list.shift();
})
.add(`${LINEAR.toLocaleString()} addBefore`, () => {
.add(`${MILLION.toLocaleString()} addBefore`, () => {
const doublyList = new DoublyLinkedList<number>();
let midNode: DoublyLinkedListNode | undefined;
const midIndex = Math.floor(LINEAR / 2);
for (let i = 0; i < LINEAR; i++) {
const midIndex = Math.floor(MILLION / 2);
for (let i = 0; i < MILLION; i++) {
doublyList.push(i);
if (i === midIndex) {
midNode = doublyList.getNode(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,16 @@ suite
.add(`${MILLION.toLocaleString()} push & shift`, () => {
const list = new SinglyLinkedList<number>();

for (let i = 0; i < MILLION; i++) {
list.push(i);
}
for (let i = 0; i < MILLION; i++) list.push(i);

for (let i = 0; i < MILLION; i++) {
list.shift();
}
for (let i = 0; i < MILLION; i++) list.shift();
})
.add(`${TEN_THOUSAND.toLocaleString()} push & pop`, () => {
const list = new SinglyLinkedList<number>();

for (let i = 0; i < TEN_THOUSAND; i++) {
list.push(i);
}
for (let i = 0; i < TEN_THOUSAND; i++) list.push(i);

for (let i = 0; i < TEN_THOUSAND; i++) {
list.pop();
}
for (let i = 0; i < TEN_THOUSAND; i++) list.pop();
})
.add(`${TEN_THOUSAND.toLocaleString()} addBefore`, () => {
const singlyList = new SinglyLinkedList<number>();
Expand Down
Loading

0 comments on commit c3db558

Please sign in to comment.