data-structure-typed 2.2.2 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +311 -1687
  3. package/README_CN.md +509 -0
  4. package/SECURITY.md +962 -11
  5. package/SECURITY.zh-CN.md +966 -0
  6. package/SPECIFICATION.md +689 -30
  7. package/SPECIFICATION.zh-CN.md +715 -0
  8. package/SPONSOR.zh-CN.md +62 -0
  9. package/SPONSOR_POLISHED.md +62 -0
  10. package/benchmark/report.html +1 -1
  11. package/benchmark/report.json +215 -172
  12. package/dist/cjs/index.cjs +163 -0
  13. package/dist/cjs/index.cjs.map +1 -1
  14. package/dist/cjs-legacy/index.cjs +164 -0
  15. package/dist/cjs-legacy/index.cjs.map +1 -1
  16. package/dist/esm/index.mjs +163 -0
  17. package/dist/esm/index.mjs.map +1 -1
  18. package/dist/esm-legacy/index.mjs +164 -0
  19. package/dist/esm-legacy/index.mjs.map +1 -1
  20. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +96 -2
  21. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +103 -7
  22. package/dist/types/data-structures/binary-tree/bst.d.ts +156 -13
  23. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +84 -35
  24. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
  25. package/dist/types/data-structures/graph/directed-graph.d.ts +126 -1
  26. package/dist/types/data-structures/graph/undirected-graph.d.ts +160 -1
  27. package/dist/types/data-structures/hash/hash-map.d.ts +110 -27
  28. package/dist/types/data-structures/heap/heap.d.ts +107 -58
  29. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +72 -404
  30. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +121 -5
  31. package/dist/types/data-structures/queue/deque.d.ts +95 -67
  32. package/dist/types/data-structures/queue/queue.d.ts +90 -34
  33. package/dist/types/data-structures/stack/stack.d.ts +58 -40
  34. package/dist/types/data-structures/trie/trie.d.ts +109 -47
  35. package/dist/types/interfaces/binary-tree.d.ts +1 -0
  36. package/dist/umd/data-structure-typed.js +164 -0
  37. package/dist/umd/data-structure-typed.js.map +1 -1
  38. package/dist/umd/data-structure-typed.min.js +3 -3
  39. package/dist/umd/data-structure-typed.min.js.map +1 -1
  40. package/package.json +3 -2
  41. package/src/data-structures/binary-tree/avl-tree.ts +96 -2
  42. package/src/data-structures/binary-tree/binary-tree.ts +117 -7
  43. package/src/data-structures/binary-tree/bst.ts +322 -13
  44. package/src/data-structures/binary-tree/red-black-tree.ts +84 -35
  45. package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
  46. package/src/data-structures/graph/directed-graph.ts +126 -1
  47. package/src/data-structures/graph/undirected-graph.ts +160 -1
  48. package/src/data-structures/hash/hash-map.ts +110 -27
  49. package/src/data-structures/heap/heap.ts +107 -58
  50. package/src/data-structures/linked-list/doubly-linked-list.ts +72 -404
  51. package/src/data-structures/linked-list/singly-linked-list.ts +121 -5
  52. package/src/data-structures/queue/deque.ts +95 -67
  53. package/src/data-structures/queue/queue.ts +90 -34
  54. package/src/data-structures/stack/stack.ts +58 -40
  55. package/src/data-structures/trie/trie.ts +109 -47
  56. package/src/interfaces/binary-tree.ts +2 -0
  57. package/test/performance/benchmark-runner.ts +14 -11
  58. package/test/performance/data-structures/binary-tree/avl-tree.test.ts +8 -8
  59. package/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts +8 -8
  60. package/test/performance/data-structures/binary-tree/binary-tree.test.ts +6 -6
  61. package/test/performance/data-structures/binary-tree/bst.test.ts +5 -5
  62. package/test/performance/data-structures/binary-tree/red-black-tree.test.ts +10 -10
  63. package/test/performance/reportor.ts +2 -1
  64. package/test/performance/single-suite-runner.ts +7 -4
  65. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +117 -0
  66. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +166 -0
  67. package/test/unit/data-structures/binary-tree/bst.test.ts +766 -8
  68. package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +89 -37
  69. package/test/unit/data-structures/graph/directed-graph.test.ts +133 -0
  70. package/test/unit/data-structures/graph/undirected-graph.test.ts +167 -0
  71. package/test/unit/data-structures/hash/hash-map.test.ts +149 -3
  72. package/test/unit/data-structures/heap/heap.test.ts +182 -47
  73. package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +118 -14
  74. package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +121 -0
  75. package/test/unit/data-structures/queue/deque.test.ts +98 -67
  76. package/test/unit/data-structures/queue/queue.test.ts +85 -51
  77. package/test/unit/data-structures/stack/stack.test.ts +142 -33
  78. package/test/unit/data-structures/trie/trie.test.ts +135 -39
  79. package/tsup.leetcode.config.js +99 -0
  80. package/typedoc.json +2 -1
  81. package/POSTS_zh-CN.md +0 -54
  82. package/README_zh-CN.md +0 -1208
  83. package/SPECIFICATION_zh-CN.md +0 -81
@@ -997,55 +997,103 @@ describe('Trie basic', () => {
997
997
  });
998
998
 
999
999
  describe('classic use', () => {
1000
- test('@example Autocomplete: Prefix validation and checking', () => {
1001
- const autocomplete = new Trie<string>(['gmail.com', 'gmail.co.nz', 'gmail.co.jp', 'yahoo.com', 'outlook.com']);
1000
+ it('@example basic Trie creation and add words', () => {
1001
+ // Create a simple Trie with initial words
1002
+ const trie = new Trie(['apple', 'app', 'apply']);
1002
1003
 
1003
- // Get all completions for a prefix
1004
- const gmailCompletions = autocomplete.getWords('gmail');
1005
- expect(gmailCompletions).toEqual(['gmail.com', 'gmail.co.nz', 'gmail.co.jp']);
1004
+ // Verify size
1005
+ expect(trie.size).toBe(3);
1006
+
1007
+ // Check if words exist
1008
+ expect(trie.has('apple')).toBe(true);
1009
+ expect(trie.has('app')).toBe(true);
1010
+
1011
+ // Add a new word
1012
+ trie.add('application');
1013
+ expect(trie.size).toBe(4);
1006
1014
  });
1007
1015
 
1008
- test('@example File System Path Operations', () => {
1009
- const fileSystem = new Trie<string>([
1010
- '/home/user/documents/file1.txt',
1011
- '/home/user/documents/file2.txt',
1012
- '/home/user/pictures/photo.jpg',
1013
- '/home/user/pictures/vacation/',
1014
- '/home/user/downloads'
1015
- ]);
1016
+ it('@example Trie getWords and prefix search', () => {
1017
+ const trie = new Trie(['apple', 'app', 'apply', 'application', 'apricot']);
1016
1018
 
1017
- // Find common directory prefix
1018
- expect(fileSystem.getLongestCommonPrefix()).toBe('/home/user/');
1019
+ // Get all words with prefix 'app'
1020
+ const appWords = trie.getWords('app');
1021
+ expect(appWords).toContain('app');
1022
+ expect(appWords).toContain('apple');
1023
+ expect(appWords).toContain('apply');
1024
+ expect(appWords).toContain('application');
1025
+ expect(appWords).not.toContain('apricot');
1026
+ });
1019
1027
 
1020
- // List all files in a directory
1021
- const documentsFiles = fileSystem.getWords('/home/user/documents/');
1022
- expect(documentsFiles).toEqual(['/home/user/documents/file1.txt', '/home/user/documents/file2.txt']);
1028
+ it('@example Trie isPrefix and isAbsolutePrefix checks', () => {
1029
+ const trie = new Trie(['tree', 'trial', 'trick', 'trip', 'trie']);
1030
+
1031
+ // Check if string is a prefix of any word
1032
+ expect(trie.hasPrefix('tri')).toBe(true);
1033
+ expect(trie.hasPrefix('tr')).toBe(true);
1034
+ expect(trie.hasPrefix('xyz')).toBe(false);
1035
+
1036
+ // Check if string is an absolute prefix (not a complete word)
1037
+ expect(trie.hasPurePrefix('tri')).toBe(true);
1038
+ expect(trie.hasPurePrefix('tree')).toBe(false); // 'tree' is a complete word
1039
+
1040
+ // Verify size
1041
+ expect(trie.size).toBe(5);
1023
1042
  });
1024
1043
 
1025
- test('@example Autocomplete: Basic word suggestions', () => {
1026
- // Create a trie for autocomplete
1027
- const autocomplete = new Trie<string>([
1028
- 'function',
1029
- 'functional',
1030
- 'functions',
1031
- 'class',
1032
- 'classes',
1033
- 'classical',
1034
- 'closure',
1035
- 'const',
1036
- 'constructor'
1037
- ]);
1044
+ it('@example Trie delete and iteration', () => {
1045
+ const trie = new Trie(['car', 'card', 'care', 'careful', 'can', 'cat']);
1038
1046
 
1039
- // Test autocomplete with different prefixes
1040
- expect(autocomplete.getWords('fun')).toEqual(['functional', 'functions', 'function']);
1041
- expect(autocomplete.getWords('cla')).toEqual(['classes', 'classical', 'class']);
1042
- expect(autocomplete.getWords('con')).toEqual(['constructor', 'const']);
1047
+ // Delete a word
1048
+ trie.delete('card');
1049
+ expect(trie.has('card')).toBe(false);
1043
1050
 
1044
- // Test with non-matching prefix
1045
- expect(autocomplete.getWords('xyz')).toEqual([]);
1051
+ // Word with same prefix still exists
1052
+ expect(trie.has('care')).toBe(true);
1053
+
1054
+ // Size decreased
1055
+ expect(trie.size).toBe(5);
1056
+
1057
+ // Iterate through all words
1058
+ const allWords = [...trie];
1059
+ expect(allWords.length).toBe(5);
1046
1060
  });
1047
1061
 
1048
- test('@example Dictionary: Case-insensitive word lookup', () => {
1062
+ it('@example Trie for autocomplete search index', () => {
1063
+ // Trie is perfect for autocomplete: O(m + k) where m is prefix length, k is results
1064
+ const searchIndex = new Trie(['typescript', 'javascript', 'python', 'java', 'rust', 'ruby', 'golang', 'kotlin']);
1065
+
1066
+ // User types 'j' - get all suggestions
1067
+ const jResults = searchIndex.getWords('j');
1068
+ expect(jResults).toContain('javascript');
1069
+ expect(jResults).toContain('java');
1070
+ expect(jResults.length).toBe(2);
1071
+
1072
+ // User types 'ja' - get more specific suggestions
1073
+ const jaResults = searchIndex.getWords('ja');
1074
+ expect(jaResults).toContain('javascript');
1075
+ expect(jaResults).toContain('java');
1076
+ expect(jaResults.length).toBe(2);
1077
+
1078
+ // User types 'jav' - even more specific
1079
+ const javResults = searchIndex.getWords('jav');
1080
+ expect(javResults).toContain('javascript');
1081
+ expect(javResults).toContain('java');
1082
+ expect(javResults.length).toBe(2);
1083
+
1084
+ // Check for common prefix
1085
+
1086
+ expect(searchIndex.hasCommonPrefix('ja')).toBe(false); // Not all words start with 'ja'
1087
+
1088
+ // Total words in index
1089
+ expect(searchIndex.size).toBe(8);
1090
+
1091
+ // Get height (depth of tree)
1092
+ const height = searchIndex.getHeight();
1093
+ expect(typeof height).toBe('number');
1094
+ });
1095
+
1096
+ it('@example Dictionary: Case-insensitive word lookup', () => {
1049
1097
  // Create a case-insensitive dictionary
1050
1098
  const dictionary = new Trie<string>([], { caseSensitive: false });
1051
1099
 
@@ -1062,7 +1110,24 @@ describe('classic use', () => {
1062
1110
  expect(dictionary.has('JAVASCRIPT')).toBe(true);
1063
1111
  });
1064
1112
 
1065
- test('@example IP Address Routing Table', () => {
1113
+ it('@example File System Path Operations', () => {
1114
+ const fileSystem = new Trie<string>([
1115
+ '/home/user/documents/file1.txt',
1116
+ '/home/user/documents/file2.txt',
1117
+ '/home/user/pictures/photo.jpg',
1118
+ '/home/user/pictures/vacation/',
1119
+ '/home/user/downloads'
1120
+ ]);
1121
+
1122
+ // Find common directory prefix
1123
+ expect(fileSystem.getLongestCommonPrefix()).toBe('/home/user/');
1124
+
1125
+ // List all files in a directory
1126
+ const documentsFiles = fileSystem.getWords('/home/user/documents/');
1127
+ expect(documentsFiles).toEqual(['/home/user/documents/file1.txt', '/home/user/documents/file2.txt']);
1128
+ });
1129
+
1130
+ it('@example IP Address Routing Table', () => {
1066
1131
  // Add IP address prefixes and their corresponding routes
1067
1132
  const routes = {
1068
1133
  '192.168.1': 'LAN_SUBNET_1',
@@ -1082,4 +1147,35 @@ describe('classic use', () => {
1082
1147
  const subnet = ip.split('.').slice(0, 3).join('.');
1083
1148
  expect(ipRoutingTable.hasPrefix(subnet)).toBe(true);
1084
1149
  });
1150
+
1151
+ it('Autocomplete: Prefix validation and checking', () => {
1152
+ const autocomplete = new Trie<string>(['gmail.com', 'gmail.co.nz', 'gmail.co.jp', 'yahoo.com', 'outlook.com']);
1153
+
1154
+ // Get all completions for a prefix
1155
+ const gmailCompletions = autocomplete.getWords('gmail');
1156
+ expect(gmailCompletions).toEqual(['gmail.com', 'gmail.co.nz', 'gmail.co.jp']);
1157
+ });
1158
+
1159
+ it('Autocomplete: Basic word suggestions', () => {
1160
+ // Create a trie for autocomplete
1161
+ const autocomplete = new Trie<string>([
1162
+ 'function',
1163
+ 'functional',
1164
+ 'functions',
1165
+ 'class',
1166
+ 'classes',
1167
+ 'classical',
1168
+ 'closure',
1169
+ 'const',
1170
+ 'constructor'
1171
+ ]);
1172
+
1173
+ // Test autocomplete with different prefixes
1174
+ expect(autocomplete.getWords('fun')).toEqual(['functional', 'functions', 'function']);
1175
+ expect(autocomplete.getWords('cla')).toEqual(['classes', 'classical', 'class']);
1176
+ expect(autocomplete.getWords('con')).toEqual(['constructor', 'const']);
1177
+
1178
+ // Test with non-matching prefix
1179
+ expect(autocomplete.getWords('xyz')).toEqual([]);
1180
+ });
1085
1181
  });
@@ -0,0 +1,99 @@
1
+ import { defineConfig } from 'tsup';
2
+ import { readdir, readFile, writeFile } from 'fs/promises';
3
+ import { join } from 'path';
4
+
5
+ const commonConfig = {
6
+ format: ['esm'],
7
+ outDir: 'dist/leetcode',
8
+ splitting: false,
9
+ sourcemap: false,
10
+ keepNames: true,
11
+ treeshake: false,
12
+ clean: true,
13
+ target: 'es2022',
14
+ minify: false,
15
+ dts: false,
16
+
17
+ outExtension() {
18
+ return { js: '.mjs' };
19
+ },
20
+
21
+ // The true ultimate solution: automatic cleaning up of comments after the build is complete
22
+ onSuccess: async () => {
23
+ const distDir = 'dist/leetcode';
24
+ try {
25
+ const files = await readdir(distDir);
26
+ let cleanedCount = 0;
27
+
28
+ for (const file of files) {
29
+ // Only .mjs and .js files are processed
30
+ if (!file.endsWith('.mjs') && !file.endsWith('.js')) continue;
31
+
32
+ const filePath = join(distDir, file);
33
+ let content = await readFile(filePath, 'utf-8');
34
+
35
+ // Step 1: Remove all block comments (including JSDoc)
36
+ content = content.replace(/\/\*[\s\S]*?\*\//g, '');
37
+
38
+ // Step 2: Remove all line comments
39
+ content = content.replace(/^\s*\/\/.*$/gm, '');
40
+
41
+ // Step 3: Remove extra blank lines (optional, delete this line if you want to keep it)
42
+ content = content.replace(/\n\s*\n/g, '\n');
43
+
44
+ await writeFile(filePath, content);
45
+ cleanedCount++;
46
+ }
47
+ } catch (err) {
48
+ process.exit(1);
49
+ }
50
+ }
51
+ };
52
+
53
+ const entries = {
54
+ // ============ Heap ============
55
+ heap: 'src/data-structures/heap/heap.ts',
56
+ 'max-heap': 'src/data-structures/heap/max-heap.ts',
57
+ 'min-heap': 'src/data-structures/heap/min-heap.ts',
58
+
59
+ // ============ Binary Trees ============
60
+ 'binary-tree': 'src/data-structures/binary-tree/binary-tree.ts',
61
+ bst: 'src/data-structures/binary-tree/bst.ts',
62
+ 'red-black-tree': 'src/data-structures/binary-tree/red-black-tree.ts',
63
+ 'avl-tree': 'src/data-structures/binary-tree/avl-tree.ts',
64
+ 'avl-tree-counter': 'src/data-structures/binary-tree/avl-tree-counter.ts',
65
+ 'avl-tree-multi-map': 'src/data-structures/binary-tree/avl-tree-multi-map.ts',
66
+ 'tree-counter': 'src/data-structures/binary-tree/tree-counter.ts',
67
+ 'tree-multi-map': 'src/data-structures/binary-tree/tree-multi-map.ts',
68
+
69
+ // ============ Graph ============
70
+ 'directed-graph': 'src/data-structures/graph/directed-graph.ts',
71
+ 'undirected-graph': 'src/data-structures/graph/undirected-graph.ts',
72
+
73
+ // ============ Hash ============
74
+ 'hash-map': 'src/data-structures/hash/hash-map.ts',
75
+
76
+ // ============ LinkedList ============
77
+ 'doubly-linked-list': 'src/data-structures/linked-list/doubly-linked-list.ts',
78
+ 'singly-linked-list': 'src/data-structures/linked-list/singly-linked-list.ts',
79
+
80
+ // ============ PriorityQueue ============
81
+ 'priority-queue': 'src/data-structures/priority-queue/priority-queue.ts',
82
+ 'max-priority-queue': 'src/data-structures/priority-queue/max-priority-queue.ts',
83
+ 'min-priority-queue': 'src/data-structures/priority-queue/min-priority-queue.ts',
84
+
85
+ // ============ Queue ============
86
+ deque: 'src/data-structures/queue/deque.ts',
87
+ queue: 'src/data-structures/queue/queue.ts',
88
+
89
+ // ============ Stack ============
90
+ stack: 'src/data-structures/stack/stack.ts',
91
+
92
+ // ============ Trie ============
93
+ trie: 'src/data-structures/trie/trie.ts'
94
+ };
95
+
96
+ export default defineConfig({
97
+ ...commonConfig,
98
+ entry: entries
99
+ });
package/typedoc.json CHANGED
@@ -1,4 +1,5 @@
1
1
  {
2
+ "cleanOutputDir": false,
2
3
  "visibilityFilters": {
3
4
  "protected": false,
4
5
  "private": false,
@@ -27,4 +28,4 @@
27
28
  "TypeAlias",
28
29
  "Reference"
29
30
  ]
30
- }
31
+ }
package/POSTS_zh-CN.md DELETED
@@ -1,54 +0,0 @@
1
- Java有java.utils,C++有STL,那JavaScript和TypeScript长期以来没有一个顺手的数据结构和算法库
2
-
3
- data-structure-typed就应运而生
4
-
5
- ## 性能
6
-
7
- ### 部分超越JavaScript内置的数据结构
8
-
9
- ### 部分超越C++
10
-
11
-
12
- ## 顺手程度
13
-
14
- ### 亲密拥抱JavaScript,TypeScript和ES6
15
-
16
- #### 提供与JavaScript中Array完全一致的API体验
17
-
18
- #### 提供生成器
19
-
20
-
21
- ### 基类中统一实现通用方法
22
-
23
- ### 完整的OOP封装
24
-
25
- #### 可复用性
26
-
27
- #### 可扩展性
28
-
29
- 为开发者提供继承所有数据结构的可能
30
-
31
- ### 摒弃以往数据结构库中同时存在Set和Map
32
-
33
- #### 原滋原味的基础数据结构
34
-
35
- 不必分别记忆Set和Map的API
36
-
37
-
38
- ## 内置算法
39
-
40
- ## 可视化
41
-
42
- ### print方法
43
-
44
- ### 可视化工具
45
-
46
- #### 数据结构可视化
47
-
48
- #### 步进式调试
49
-
50
- ## 多种模块系统的支持
51
-
52
-
53
-
54
-