From dde65b2bd992a97ee90d0fd55430edd0b93e5c0f Mon Sep 17 00:00:00 2001 From: jack <1395093509@qq.com> Date: Thu, 14 Feb 2019 16:30:28 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E5=AD=A6=E4=B9=A0=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + README.zh-CN.md | 384 ++++++++++---------- examples/README.md | 73 ++++ examples/factorial/README.md | 9 + examples/fibonacci/.circleci/config.yml | 39 ++ examples/fibonacci/README.md | 10 + examples/fibonacci/__test__/fastfib.spec.js | 18 + examples/fibonacci/benchmark/index.js | 30 ++ examples/fibonacci/package.json | 37 ++ examples/fibonacci/src/index.js | 5 + examples/fibonacci/src/iter.js | 20 + examples/fibonacci/src/recurse.js | 15 + examples/fibonacci/src/tail.js | 25 ++ examples/fibonacci/ts/index.ts | 5 + examples/fibonacci/ts/iter.ts | 24 ++ examples/fibonacci/ts/recurse.ts | 14 + examples/fibonacci/ts/tail.ts | 25 ++ examples/fibonacci/ts/tempCodeRunnerFile.ts | 22 ++ examples/lz77/README.md | 21 ++ examples/lz78/README.md | 7 + examples/uuid/README.md | 19 + examples/uuid/src/guid.js | 91 +++++ examples/uuid/src/uuid.js | 66 ++++ jest.config.js | 6 +- src/data-types/README.md | 72 ++++ src/data-types/index.js | 20 + ts/data-types/README.md | 3 + 27 files changed, 873 insertions(+), 189 deletions(-) create mode 100644 examples/README.md create mode 100644 examples/factorial/README.md create mode 100644 examples/fibonacci/.circleci/config.yml create mode 100644 examples/fibonacci/README.md create mode 100644 examples/fibonacci/__test__/fastfib.spec.js create mode 100644 examples/fibonacci/benchmark/index.js create mode 100644 examples/fibonacci/package.json create mode 100644 examples/fibonacci/src/index.js create mode 100644 examples/fibonacci/src/iter.js create mode 100644 examples/fibonacci/src/recurse.js create mode 100644 examples/fibonacci/src/tail.js create mode 100644 examples/fibonacci/ts/index.ts create mode 100644 examples/fibonacci/ts/iter.ts create mode 100644 examples/fibonacci/ts/recurse.ts create mode 100644 examples/fibonacci/ts/tail.ts create mode 100644 examples/fibonacci/ts/tempCodeRunnerFile.ts create mode 100644 examples/lz77/README.md create mode 100644 examples/lz78/README.md create mode 100644 examples/uuid/README.md create mode 100644 examples/uuid/src/guid.js create mode 100644 examples/uuid/src/uuid.js create mode 100644 src/data-types/README.md create mode 100644 src/data-types/index.js create mode 100644 ts/data-types/README.md diff --git a/.gitignore b/.gitignore index e128b69788..f46ad49b8e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ node_modules coverage .vscode .DS_Store + +temp diff --git a/README.zh-CN.md b/README.zh-CN.md index cdef9cabea..dba0515b22 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,5 +1,11 @@ # JavaScript 算法与数据结构 +TypeScript 版本 + +参考 + +- https://github.com/loiane/javascript-datastructures-algorithms + [![CI](https://github.com/trekhleb/javascript-algorithms/workflows/CI/badge.svg)](https://github.com/trekhleb/javascript-algorithms/actions?query=workflow%3ACI+branch%3Amaster) [![codecov](https://codecov.io/gh/trekhleb/javascript-algorithms/branch/master/graph/badge.svg)](https://codecov.io/gh/trekhleb/javascript-algorithms) @@ -25,7 +31,7 @@ _Read this in other languages:_ [_Tiếng Việt_](README.vi-VN.md), [_Deutsch_](README.de-DE.md) -*注意:这个项目仅用于学习和研究,**不是**用于生产环境。* +_注意:这个项目仅用于学习和研究,**不是**用于生产环境。_ ## 数据结构 @@ -33,23 +39,23 @@ _Read this in other languages:_ `B` - 初学者, `A` - 进阶 -* `B` [链表](src/data-structures/linked-list/README.zh-CN.md) -* `B` [双向链表](src/data-structures/doubly-linked-list/README.zh-CN.md) -* `B` [队列](src/data-structures/queue/README.zh-CN.md) -* `B` [栈](src/data-structures/stack/README.zh-CN.md) -* `B` [哈希表(散列)](src/data-structures/hash-table/README.zh-CN.md) -* `B` [堆](src/data-structures/heap/README.zh-CN.md) - 最大堆 & 最小堆 -* `B` [优先队列](src/data-structures/priority-queue/README.zh-CN.md) -* `A` [字典树](src/data-structures/trie/README.zh-CN.md) -* `A` [树](src/data-structures/tree/README.zh-CN.md) - * `A` [二叉查找树](src/data-structures/tree/binary-search-tree) - * `A` [AVL 树](src/data-structures/tree/avl-tree) - * `A` [红黑树](src/data-structures/tree/red-black-tree) - * `A` [线段树](src/data-structures/tree/segment-tree) - 使用 `最小/最大/总和` 范围查询示例 - * `A` [树状数组](src/data-structures/tree/fenwick-tree) (二叉索引树) -* `A` [图](src/data-structures/graph/README.zh-CN.md) (有向图与无向图) -* `A` [并查集](src/data-structures/disjoint-set) -* `A` [布隆过滤器](src/data-structures/bloom-filter) +- `B` [链表](src/data-structures/linked-list/README.zh-CN.md) +- `B` [双向链表](src/data-structures/doubly-linked-list/README.zh-CN.md) +- `B` [队列](src/data-structures/queue/README.zh-CN.md) +- `B` [栈](src/data-structures/stack/README.zh-CN.md) +- `B` [哈希表(散列)](src/data-structures/hash-table/README.zh-CN.md) +- `B` [堆](src/data-structures/heap/README.zh-CN.md) - 最大堆 & 最小堆 +- `B` [优先队列](src/data-structures/priority-queue/README.zh-CN.md) +- `A` [字典树](src/data-structures/trie/README.zh-CN.md) +- `A` [树](src/data-structures/tree/README.zh-CN.md) + - `A` [二叉查找树](src/data-structures/tree/binary-search-tree) + - `A` [AVL 树](src/data-structures/tree/avl-tree) + - `A` [红黑树](src/data-structures/tree/red-black-tree) + - `A` [线段树](src/data-structures/tree/segment-tree) - 使用 `最小/最大/总和` 范围查询示例 + - `A` [树状数组](src/data-structures/tree/fenwick-tree) (二叉索引树) +- `A` [图](src/data-structures/graph/README.zh-CN.md) (有向图与无向图) +- `A` [并查集](src/data-structures/disjoint-set) +- `A` [布隆过滤器](src/data-structures/bloom-filter) ## 算法 @@ -59,153 +65,154 @@ _Read this in other languages:_ ### 算法主题 -* **数学** - * `B` [位运算](src/algorithms/math/bits) - set/get/update/clear 位、乘以/除以二进制位 、变负等 - * `B` [阶乘](src/algorithms/math/factorial/README.zh-CN.md) - * `B` [斐波那契数](src/algorithms/math/fibonacci) - `经典` 和 `闭式` 版本 - * `B` [素数检测](src/algorithms/math/primality-test) (排除法) - * `B` [欧几里得算法](src/algorithms/math/euclidean-algorithm) - 计算最大公约数 (GCD) - * `B` [最小公倍数](src/algorithms/math/least-common-multiple) (LCM) - * `B` [素数筛](src/algorithms/math/sieve-of-eratosthenes) - 查找任意给定范围内的所有素数 - * `B` [判断 2 次方数](src/algorithms/math/is-power-of-two) - 检查数字是否为 2 的幂 (原生和按位算法) - * `B` [杨辉三角形](src/algorithms/math/pascal-triangle) - * `B` [复数](src/algorithms/math/complex-number) - 复数及其基本运算 - * `B` [弧度和角](src/algorithms/math/radian) - 弧度与角的相互转换 - * `B` [快速算次方](src/algorithms/math/fast-powering) - * `A` [整数拆分](src/algorithms/math/integer-partition) - * `A` [割圆术](src/algorithms/math/liu-hui) - 基于 N-gons 的近似 π 计算 - * `A` [离散傅里叶变换](src/algorithms/math/fourier-transform) - 把时间信号解析成构成它的频率 -* **集合** - * `B` [笛卡尔积](src/algorithms/sets/cartesian-product) - 多集合结果 - * `A` [洗牌算法](src/algorithms/sets/fisher-yates) - 随机置换有限序列 - * `A` [幂集](src/algorithms/sets/power-set) - 该集合的所有子集 - * `A` [排列](src/algorithms/sets/permutations) (有/无重复) - * `A` [组合](src/algorithms/sets/combinations) (有/无重复) - * `A` [最长公共子序列](src/algorithms/sets/longest-common-subsequence) (LCS) - * `A` [最长递增子序列](src/algorithms/sets/longest-increasing-subsequence) - * `A` [最短公共父序列](src/algorithms/sets/shortest-common-supersequence) (SCS) - * `A` [背包问题](src/algorithms/sets/knapsack-problem) - `0/1` 和 `无边界` 问题 - * `A` [最大子数列问题](src/algorithms/sets/maximum-subarray) - `BF 算法` 和 `动态规划` - * `A` [组合求和](src/algorithms/sets/combination-sum) - 查找形成特定总和的所有组合 -* **字符串** - * `B` [汉明距离](src/algorithms/string/hamming-distance) - 符号不同的位置数 - * `A` [莱温斯坦距离](src/algorithms/string/levenshtein-distance) - 两个序列之间的最小编辑距离 - * `A` [Knuth–Morris–Pratt 算法](src/algorithms/string/knuth-morris-pratt) KMP 算法 - 子串搜索 (模式匹配) - * `A` [字符串快速查找](src/algorithms/string/z-algorithm) - 子串搜索 (模式匹配) - * `A` [Rabin Karp 算法](src/algorithms/string/rabin-karp) - 子串搜索 - * `A` [最长公共子串](src/algorithms/string/longest-common-substring) - * `A` [正则表达式匹配](src/algorithms/string/regular-expression-matching) -* **搜索** - * `B` [线性搜索](src/algorithms/search/linear-search) - * `B` [跳转搜索/块搜索](src/algorithms/search/jump-search) - 搜索有序数组 - * `B` [二分查找](src/algorithms/search/binary-search) - 搜索有序数组 - * `B` [插值搜索](src/algorithms/search/interpolation-search) - 搜索均匀分布的有序数组 -* **排序** - * `B` [冒泡排序](src/algorithms/sorting/bubble-sort) - * `B` [选择排序](src/algorithms/sorting/selection-sort) - * `B` [插入排序](src/algorithms/sorting/insertion-sort) - * `B` [堆排序](src/algorithms/sorting/heap-sort) - * `B` [归并排序](src/algorithms/sorting/merge-sort) - * `B` [快速排序](src/algorithms/sorting/quick-sort) - in-place (原地) 和 non-in-place 版本 - * `B` [希尔排序](src/algorithms/sorting/shell-sort) - * `B` [计数排序](src/algorithms/sorting/counting-sort) - * `B` [基数排序](src/algorithms/sorting/radix-sort) -* **链表** +- **数学** + - `B` [位运算](src/algorithms/math/bits) - set/get/update/clear 位、乘以/除以二进制位 、变负等 + - `B` [阶乘](src/algorithms/math/factorial/README.zh-CN.md) + - `B` [斐波那契数](src/algorithms/math/fibonacci) - `经典` 和 `闭式` 版本 + - `B` [素数检测](src/algorithms/math/primality-test) (排除法) + - `B` [欧几里得算法](src/algorithms/math/euclidean-algorithm) - 计算最大公约数 (GCD) + - `B` [最小公倍数](src/algorithms/math/least-common-multiple) (LCM) + - `B` [素数筛](src/algorithms/math/sieve-of-eratosthenes) - 查找任意给定范围内的所有素数 + - `B` [判断 2 次方数](src/algorithms/math/is-power-of-two) - 检查数字是否为 2 的幂 (原生和按位算法) + - `B` [杨辉三角形](src/algorithms/math/pascal-triangle) + - `B` [复数](src/algorithms/math/complex-number) - 复数及其基本运算 + - `B` [弧度和角](src/algorithms/math/radian) - 弧度与角的相互转换 + - `B` [快速算次方](src/algorithms/math/fast-powering) + - `A` [整数拆分](src/algorithms/math/integer-partition) + - `A` [割圆术](src/algorithms/math/liu-hui) - 基于 N-gons 的近似 π 计算 + - `A` [离散傅里叶变换](src/algorithms/math/fourier-transform) - 把时间信号解析成构成它的频率 +- **集合** + - `B` [笛卡尔积](src/algorithms/sets/cartesian-product) - 多集合结果 + - `A` [洗牌算法](src/algorithms/sets/fisher-yates) - 随机置换有限序列 + - `A` [幂集](src/algorithms/sets/power-set) - 该集合的所有子集 + - `A` [排列](src/algorithms/sets/permutations) (有/无重复) + - `A` [组合](src/algorithms/sets/combinations) (有/无重复) + - `A` [最长公共子序列](src/algorithms/sets/longest-common-subsequence) (LCS) + - `A` [最长递增子序列](src/algorithms/sets/longest-increasing-subsequence) + - `A` [最短公共父序列](src/algorithms/sets/shortest-common-supersequence) (SCS) + - `A` [背包问题](src/algorithms/sets/knapsack-problem) - `0/1` 和 `无边界` 问题 + - `A` [最大子数列问题](src/algorithms/sets/maximum-subarray) - `BF 算法` 和 `动态规划` + - `A` [组合求和](src/algorithms/sets/combination-sum) - 查找形成特定总和的所有组合 +- **字符串** + - `B` [汉明距离](src/algorithms/string/hamming-distance) - 符号不同的位置数 + - `A` [莱温斯坦距离](src/algorithms/string/levenshtein-distance) - 两个序列之间的最小编辑距离 + - `A` [Knuth–Morris–Pratt 算法](src/algorithms/string/knuth-morris-pratt) KMP 算法 - 子串搜索 (模式匹配) + - `A` [字符串快速查找](src/algorithms/string/z-algorithm) - 子串搜索 (模式匹配) + - `A` [Rabin Karp 算法](src/algorithms/string/rabin-karp) - 子串搜索 + - `A` [最长公共子串](src/algorithms/string/longest-common-substring) + - `A` [正则表达式匹配](src/algorithms/string/regular-expression-matching) +- **搜索** + - `B` [线性搜索](src/algorithms/search/linear-search) + - `B` [跳转搜索/块搜索](src/algorithms/search/jump-search) - 搜索有序数组 + - `B` [二分查找](src/algorithms/search/binary-search) - 搜索有序数组 + - `B` [插值搜索](src/algorithms/search/interpolation-search) - 搜索均匀分布的有序数组 +- **排序** + - `B` [冒泡排序](src/algorithms/sorting/bubble-sort) + - `B` [选择排序](src/algorithms/sorting/selection-sort) + - `B` [插入排序](src/algorithms/sorting/insertion-sort) + - `B` [堆排序](src/algorithms/sorting/heap-sort) + - `B` [归并排序](src/algorithms/sorting/merge-sort) + - `B` [快速排序](src/algorithms/sorting/quick-sort) - in-place (原地) 和 non-in-place 版本 + - `B` [希尔排序](src/algorithms/sorting/shell-sort) + - `B` [计数排序](src/algorithms/sorting/counting-sort) + - `B` [基数排序](src/algorithms/sorting/radix-sort) +- **链表** - `B` [正向遍历](src/algorithms/linked-list/traversal) - `B` [反向遍历](src/algorithms/linked-list/reverse-traversal) -* **树** - * `B` [深度优先搜索](src/algorithms/tree/depth-first-search) (DFS) - * `B` [广度优先搜索](src/algorithms/tree/breadth-first-search) (BFS) -* **图** - * `B` [深度优先搜索](src/algorithms/graph/depth-first-search) (DFS) - * `B` [广度优先搜索](src/algorithms/graph/breadth-first-search) (BFS) - * `B` [克鲁斯克尔演算法](src/algorithms/graph/kruskal) - 寻找加权无向图的最小生成树 (MST) - * `A` [戴克斯特拉算法](src/algorithms/graph/dijkstra) - 找到图中所有顶点的最短路径 - * `A` [贝尔曼-福特算法](src/algorithms/graph/bellman-ford) - 找到图中所有顶点的最短路径 - * `A` [弗洛伊德算法](src/algorithms/graph/floyd-warshall) - 找到所有顶点对 之间的最短路径 - * `A` [判圈算法](src/algorithms/graph/detect-cycle) - 对于有向图和无向图 (基于 DFS 和不相交集的版本) - * `A` [普林演算法](src/algorithms/graph/prim) - 寻找加权无向图的最小生成树 (MST) - * `A` [拓扑排序](src/algorithms/graph/topological-sorting) - DFS 方法 - * `A` [关节点](src/algorithms/graph/articulation-points) - Tarjan 算法 (基于 DFS) - * `A` [桥](src/algorithms/graph/bridges) - 基于 DFS 的算法 - * `A` [欧拉回径与一笔画问题](src/algorithms/graph/eulerian-path) - Fleury 的算法 - 一次访问每个边 - * `A` [哈密顿图](src/algorithms/graph/hamiltonian-cycle) - 恰好访问每个顶点一次 - * `A` [强连通分量](src/algorithms/graph/strongly-connected-components) - Kosaraju 算法 - * `A` [旅行推销员问题](src/algorithms/graph/travelling-salesman) - 尽可能以最短的路线访问每个城市并返回原始城市 -* **加密** - * `B` [多项式 hash](src/algorithms/cryptography/polynomial-hash) - 基于多项式的 rolling hash 函数 -* **机器学习** - * `B` [NanoNeuron](https://github.com/trekhleb/nano-neuron) -7个简单的JS函数,说明机器如何实际学习(向前/向后传播) -* **未分类** - * `B` [汉诺塔](src/algorithms/uncategorized/hanoi-tower) - * `B` [旋转矩阵](src/algorithms/uncategorized/square-matrix-rotation) - 原地算法 - * `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) - 回溯,、动态编程 (自上而下+自下而上) 和贪婪的例子 - * `B` [独特(唯一) 路径](src/algorithms/uncategorized/unique-paths) - 回溯、动态编程和基于 Pascal 三角形的例子 - * `B` [雨水收集](src/algorithms/uncategorized/rain-terraces) - 诱捕雨水问题 (动态编程和暴力版本) - * `B` [递归楼梯](src/algorithms/uncategorized/recursive-staircase) - 计算有共有多少种方法可以到达顶层 (4 种解题方案) - * `A` [八皇后问题](src/algorithms/uncategorized/n-queens) - * `A` [骑士巡逻](src/algorithms/uncategorized/knight-tour) +- **树** + - `B` [深度优先搜索](src/algorithms/tree/depth-first-search) (DFS) + - `B` [广度优先搜索](src/algorithms/tree/breadth-first-search) (BFS) +- **图** + - `B` [深度优先搜索](src/algorithms/graph/depth-first-search) (DFS) + - `B` [广度优先搜索](src/algorithms/graph/breadth-first-search) (BFS) + - `B` [克鲁斯克尔演算法](src/algorithms/graph/kruskal) - 寻找加权无向图的最小生成树 (MST) + - `A` [戴克斯特拉算法](src/algorithms/graph/dijkstra) - 找到图中所有顶点的最短路径 + - `A` [贝尔曼-福特算法](src/algorithms/graph/bellman-ford) - 找到图中所有顶点的最短路径 + - `A` [弗洛伊德算法](src/algorithms/graph/floyd-warshall) - 找到所有顶点对 之间的最短路径 + - `A` [判圈算法](src/algorithms/graph/detect-cycle) - 对于有向图和无向图 (基于 DFS 和不相交集的版本) + - `A` [普林演算法](src/algorithms/graph/prim) - 寻找加权无向图的最小生成树 (MST) + - `A` [拓扑排序](src/algorithms/graph/topological-sorting) - DFS 方法 + - `A` [关节点](src/algorithms/graph/articulation-points) - Tarjan 算法 (基于 DFS) + - `A` [桥](src/algorithms/graph/bridges) - 基于 DFS 的算法 + - `A` [欧拉回径与一笔画问题](src/algorithms/graph/eulerian-path) - Fleury 的算法 - 一次访问每个边 + - `A` [哈密顿图](src/algorithms/graph/hamiltonian-cycle) - 恰好访问每个顶点一次 + - `A` [强连通分量](src/algorithms/graph/strongly-connected-components) - Kosaraju 算法 + - `A` [旅行推销员问题](src/algorithms/graph/travelling-salesman) - 尽可能以最短的路线访问每个城市并返回原始城市 +- **加密** + - `B` [多项式 hash](src/algorithms/cryptography/polynomial-hash) - 基于多项式的 rolling hash 函数 +- **机器学习** + - `B` [NanoNeuron](https://github.com/trekhleb/nano-neuron) -7 个简单的 JS 函数,说明机器如何实际学习(向前/向后传播) +- **未分类** + - `B` [汉诺塔](src/algorithms/uncategorized/hanoi-tower) + - `B` [旋转矩阵](src/algorithms/uncategorized/square-matrix-rotation) - 原地算法 + - `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) - 回溯,、动态编程 (自上而下+自下而上) 和贪婪的例子 + - `B` [独特(唯一) 路径](src/algorithms/uncategorized/unique-paths) - 回溯、动态编程和基于 Pascal 三角形的例子 + - `B` [雨水收集](src/algorithms/uncategorized/rain-terraces) - 诱捕雨水问题 (动态编程和暴力版本) + - `B` [递归楼梯](src/algorithms/uncategorized/recursive-staircase) - 计算有共有多少种方法可以到达顶层 (4 种解题方案) + - `A` [八皇后问题](src/algorithms/uncategorized/n-queens) + - `A` [骑士巡逻](src/algorithms/uncategorized/knight-tour) ### 算法范式 算法范式是一种通用方法,基于一类算法的设计。这是比算法更高的抽象,就像算法是比计算机程序更高的抽象。 -* **BF 算法** - `查找/搜索` 所有可能性并选择最佳解决方案 - * `B` [线性搜索](src/algorithms/search/linear-search) - * `B` [雨水收集](src/algorithms/uncategorized/rain-terraces) - 诱导雨水问题 - * `B` [递归楼梯](src/algorithms/uncategorized/recursive-staircase) - 计算有共有多少种方法可以到达顶层 (4 种解题方案) - * `A` [最大子数列](src/algorithms/sets/maximum-subarray) - * `A` [旅行推销员问题](src/algorithms/graph/travelling-salesman) - 尽可能以最短的路线访问每个城市并返回原始城市 - * `A` [离散傅里叶变换](src/algorithms/math/fourier-transform) - 把时间信号解析成构成它的频率 -* **贪心法** - 在当前选择最佳选项,不考虑以后情况 - * `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) - * `A` [背包问题](src/algorithms/sets/knapsack-problem) - * `A` [戴克斯特拉算法](src/algorithms/graph/dijkstra) - 找到所有图顶点的最短路径 - * `A` [普里姆算法](src/algorithms/graph/prim) - 寻找加权无向图的最小生成树 (MST) - * `A` [克鲁斯卡尔算法](src/algorithms/graph/kruskal) - 寻找加权无向图的最小生成树 (MST) -* **分治法** - 将问题分成较小的部分,然后解决这些部分 - * `B` [二分查找](src/algorithms/search/binary-search) - * `B` [汉诺塔](src/algorithms/uncategorized/hanoi-tower) - * `B` [杨辉三角形](src/algorithms/math/pascal-triangle) - * `B` [欧几里得算法](src/algorithms/math/euclidean-algorithm) - 计算最大公约数 (GCD) - * `B` [归并排序](src/algorithms/sorting/merge-sort) - * `B` [快速排序](src/algorithms/sorting/quick-sort) - * `B` [树深度优先搜索](src/algorithms/tree/depth-first-search) (DFS) - * `B` [图深度优先搜索](src/algorithms/graph/depth-first-search) (DFS) - * `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) - * `B` [快速算次方](src/algorithms/math/fast-powering) - * `A` [排列](src/algorithms/sets/permutations) (有/无重复) - * `A` [组合](src/algorithms/sets/combinations) (有/无重复) -* **动态规划(Dynamic programming)** - 使用以前找到的子解决方案构建解决方案 - * `B` [斐波那契数](src/algorithms/math/fibonacci) - * `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) - * `B` [独特路径](src/algorithms/uncategorized/unique-paths) - * `B` [雨水收集](src/algorithms/uncategorized/rain-terraces) - 疏导雨水问题 - * `B` [递归楼梯](src/algorithms/uncategorized/recursive-staircase) - 计算有共有多少种方法可以到达顶层 (4 种解题方案) - * `A` [莱温斯坦距离](src/algorithms/string/levenshtein-distance) - 两个序列之间的最小编辑距离 - * `A` [最长公共子序列](src/algorithms/sets/longest-common-subsequence) (LCS) - * `A` [最长公共子串](src/algorithms/string/longest-common-substring) - * `A` [最长递增子序列](src/algorithms/sets/longest-increasing-subsequence) - * `A` [最短公共子序列](src/algorithms/sets/shortest-common-supersequence) - * `A` [0-1背包问题](src/algorithms/sets/knapsack-problem) - * `A` [整数拆分](src/algorithms/math/integer-partition) - * `A` [最大子数列](src/algorithms/sets/maximum-subarray) - * `A` [贝尔曼-福特算法](src/algorithms/graph/bellman-ford) - 找到所有图顶点的最短路径 - * `A` [弗洛伊德算法](src/algorithms/graph/floyd-warshall) - 找到所有顶点对之间的最短路径 - * `A` [正则表达式匹配](src/algorithms/string/regular-expression-matching) -* **回溯法** - 类似于 `BF 算法` 试图产生所有可能的解决方案,但每次生成解决方案测试如果它满足所有条件,那么只有继续生成后续解决方案。否则回溯并继续寻找不同路径的解决方案。 - * `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) - * `B` [独特路径](src/algorithms/uncategorized/unique-paths) - * `A` [幂集](src/algorithms/sets/power-set) - 该集合的所有子集 - * `A` [哈密顿图](src/algorithms/graph/hamiltonian-cycle) - 恰好访问每个顶点一次 - * `A` [八皇后问题](src/algorithms/uncategorized/n-queens) - * `A` [骑士巡逻](src/algorithms/uncategorized/knight-tour) - * `A` [组合求和](src/algorithms/sets/combination-sum) - 从规定的总和中找出所有的组合 -* **Branch & Bound** - 记住在回溯搜索的每个阶段找到的成本最低的解决方案,并使用到目前为止找到的成本最小值作为下限。以便丢弃成本大于最小值的解决方案。通常,使用 BFS 遍历以及状态空间树的 DFS 遍历。 +- **BF 算法** - `查找/搜索` 所有可能性并选择最佳解决方案 + - `B` [线性搜索](src/algorithms/search/linear-search) + - `B` [雨水收集](src/algorithms/uncategorized/rain-terraces) - 诱导雨水问题 + - `B` [递归楼梯](src/algorithms/uncategorized/recursive-staircase) - 计算有共有多少种方法可以到达顶层 (4 种解题方案) + - `A` [最大子数列](src/algorithms/sets/maximum-subarray) + - `A` [旅行推销员问题](src/algorithms/graph/travelling-salesman) - 尽可能以最短的路线访问每个城市并返回原始城市 + - `A` [离散傅里叶变换](src/algorithms/math/fourier-transform) - 把时间信号解析成构成它的频率 +- **贪心法** - 在当前选择最佳选项,不考虑以后情况 + - `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) + - `A` [背包问题](src/algorithms/sets/knapsack-problem) + - `A` [戴克斯特拉算法](src/algorithms/graph/dijkstra) - 找到所有图顶点的最短路径 + - `A` [普里姆算法](src/algorithms/graph/prim) - 寻找加权无向图的最小生成树 (MST) + - `A` [克鲁斯卡尔算法](src/algorithms/graph/kruskal) - 寻找加权无向图的最小生成树 (MST) +- **分治法** - 将问题分成较小的部分,然后解决这些部分 + - `B` [二分查找](src/algorithms/search/binary-search) + - `B` [汉诺塔](src/algorithms/uncategorized/hanoi-tower) + - `B` [杨辉三角形](src/algorithms/math/pascal-triangle) + - `B` [欧几里得算法](src/algorithms/math/euclidean-algorithm) - 计算最大公约数 (GCD) + - `B` [归并排序](src/algorithms/sorting/merge-sort) + - `B` [快速排序](src/algorithms/sorting/quick-sort) + - `B` [树深度优先搜索](src/algorithms/tree/depth-first-search) (DFS) + - `B` [图深度优先搜索](src/algorithms/graph/depth-first-search) (DFS) + - `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) + - `B` [快速算次方](src/algorithms/math/fast-powering) + - `A` [排列](src/algorithms/sets/permutations) (有/无重复) + - `A` [组合](src/algorithms/sets/combinations) (有/无重复) +- **动态规划(Dynamic programming)** - 使用以前找到的子解决方案构建解决方案 + - `B` [斐波那契数](src/algorithms/math/fibonacci) + - `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) + - `B` [独特路径](src/algorithms/uncategorized/unique-paths) + - `B` [雨水收集](src/algorithms/uncategorized/rain-terraces) - 疏导雨水问题 + - `B` [递归楼梯](src/algorithms/uncategorized/recursive-staircase) - 计算有共有多少种方法可以到达顶层 (4 种解题方案) + - `A` [莱温斯坦距离](src/algorithms/string/levenshtein-distance) - 两个序列之间的最小编辑距离 + - `A` [最长公共子序列](src/algorithms/sets/longest-common-subsequence) (LCS) + - `A` [最长公共子串](src/algorithms/string/longest-common-substring) + - `A` [最长递增子序列](src/algorithms/sets/longest-increasing-subsequence) + - `A` [最短公共子序列](src/algorithms/sets/shortest-common-supersequence) + - `A` [0-1 背包问题](src/algorithms/sets/knapsack-problem) + - `A` [整数拆分](src/algorithms/math/integer-partition) + - `A` [最大子数列](src/algorithms/sets/maximum-subarray) + - `A` [贝尔曼-福特算法](src/algorithms/graph/bellman-ford) - 找到所有图顶点的最短路径 + - `A` [弗洛伊德算法](src/algorithms/graph/floyd-warshall) - 找到所有顶点对之间的最短路径 + - `A` [正则表达式匹配](src/algorithms/string/regular-expression-matching) +- **回溯法** - 类似于 `BF 算法` 试图产生所有可能的解决方案,但每次生成解决方案测试如果它满足所有条件,那么只有继续生成后续解决方案。否则回溯并继续寻找不同路径的解决方案。 + - `B` [跳跃游戏](src/algorithms/uncategorized/jump-game) + - `B` [独特路径](src/algorithms/uncategorized/unique-paths) + - `A` [幂集](src/algorithms/sets/power-set) - 该集合的所有子集 + - `A` [哈密顿图](src/algorithms/graph/hamiltonian-cycle) - 恰好访问每个顶点一次 + - `A` [八皇后问题](src/algorithms/uncategorized/n-queens) + - `A` [骑士巡逻](src/algorithms/uncategorized/knight-tour) + - `A` [组合求和](src/algorithms/sets/combination-sum) - 从规定的总和中找出所有的组合 +- **Branch & Bound** - 记住在回溯搜索的每个阶段找到的成本最低的解决方案,并使用到目前为止找到的成本最小值作为下限。以便丢弃成本大于最小值的解决方案。通常,使用 BFS 遍历以及状态空间树的 DFS 遍历。 ## 如何使用本仓库 **安装依赖** + ``` npm install ``` @@ -225,6 +232,7 @@ npm test ``` **按照名称执行测试** + ``` npm test -- 'LinkedList' ``` @@ -245,53 +253,53 @@ npm test -- 'playground' [▶ YouTube](https://www.youtube.com/playlist?list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) -### 大O符号 +### 大 O 符号 -大O符号中指定的算法的增长顺序。 +大 O 符号中指定的算法的增长顺序。 ![Big O graphs](./assets/big-o-graph.png) 源: [Big O Cheat Sheet](http://bigocheatsheet.com/). -以下是一些最常用的 大O标记法 列表以及它们与不同大小输入数据的性能比较。 +以下是一些最常用的 大 O 标记法 列表以及它们与不同大小输入数据的性能比较。 -| 大O标记法 | 计算10个元素 | 计算100个元素 | 计算1000个元素 | -| -------------- | ---------------------------- | ----------------------------- | ------------------------------- | -| **O(1)** | 1 | 1 | 1 | -| **O(log N)** | 3 | 6 | 9 | -| **O(N)** | 10 | 100 | 1000 | -| **O(N log N)** | 30 | 600 | 9000 | -| **O(N^2)** | 100 | 10000 | 1000000 | -| **O(2^N)** | 1024 | 1.26e+29 | 1.07e+301 | -| **O(N!)** | 3628800 | 9.3e+157 | 4.02e+2567 | +| 大 O 标记法 | 计算 10 个元素 | 计算 100 个元素 | 计算 1000 个元素 | +| -------------- | -------------- | --------------- | ---------------- | +| **O(1)** | 1 | 1 | 1 | +| **O(log N)** | 3 | 6 | 9 | +| **O(N)** | 10 | 100 | 1000 | +| **O(N log N)** | 30 | 600 | 9000 | +| **O(N^2)** | 100 | 10000 | 1000000 | +| **O(2^N)** | 1024 | 1.26e+29 | 1.07e+301 | +| **O(N!)** | 3628800 | 9.3e+157 | 4.02e+2567 | ### 数据结构操作的复杂性 -| 数据结构 | 连接 | 查找 | 插入 | 删除 | 备注 | -| -------------- | :----: | :----: | :----: | :----: | ---- | -| **数组** | 1 | n | n | n | | -| **栈** | n | n | 1 | 1 | | -| **队列** | n | n | 1 | 1 | | -| **链表** | n | n | 1 | 1 | | +| 数据结构 | 连接 | 查找 | 插入 | 删除 | 备注 | +| -------------- | :----: | :----: | :----: | :----: | ------------------------------------ | +| **数组** | 1 | n | n | n | | +| **栈** | n | n | 1 | 1 | | +| **队列** | n | n | 1 | 1 | | +| **链表** | n | n | 1 | 1 | | | **哈希表** | - | n | n | n | 在完全哈希函数情况下,复杂度是 O(1) | -| **二分查找树** | n | n | n | n | 在平衡树情况下,复杂度是 O(log(n)) | -| **B 树** | log(n) | log(n) | log(n) | log(n) | | -| **红黑树** | log(n) | log(n) | log(n) | log(n) | | -| **AVL 树** | log(n) | log(n) | log(n) | log(n) | | -| **布隆过滤器** | - | 1 | 1 | - | 存在一定概率的判断错误(误判成存在) | +| **二分查找树** | n | n | n | n | 在平衡树情况下,复杂度是 O(log(n)) | +| **B 树** | log(n) | log(n) | log(n) | log(n) | | +| **红黑树** | log(n) | log(n) | log(n) | log(n) | | +| **AVL 树** | log(n) | log(n) | log(n) | log(n) | | +| **布隆过滤器** | - | 1 | 1 | - | 存在一定概率的判断错误(误判成存在) | ### 数组排序算法的复杂性 -| 名称 | 最优 | 平均 | 最坏 | 内存 | 稳定 | 备注 | -| --------------------- | :-------: | :-------: | :-----------: | :-------: | :-------: | --------------------- | -| **冒泡排序** | n | n^2 | n^2 | 1 | Yes | | -| **插入排序** | n | n^2 | n^2 | 1 | Yes | | -| **选择排序** | n^2 | n^2 | n^2 | 1 | No | | -| **堆排序** | n log(n) | n log(n) | n log(n) | 1 | No | | -| **归并排序** | n log(n) | n log(n) | n log(n) | n | Yes | | -| **快速排序** | n log(n) | n log(n) | n^2 | log(n) | No | 在 in-place 版本下,内存复杂度通常是 O(log(n)) | -| **希尔排序** | n log(n) | 取决于差距序列 | n (log(n))^2 | 1 | No | | -| **计数排序** | n + r | n + r | n + r | n + r | Yes | r - 数组里最大的数 | -| **基数排序** | n * k | n * k | n * k | n + k | Yes | k - 最长 key 的升序 | +| 名称 | 最优 | 平均 | 最坏 | 内存 | 稳定 | 备注 | +| ------------ | :------: | :------------: | :----------: | :----: | :--: | ---------------------------------------------- | +| **冒泡排序** | n | n^2 | n^2 | 1 | Yes | | +| **插入排序** | n | n^2 | n^2 | 1 | Yes | | +| **选择排序** | n^2 | n^2 | n^2 | 1 | No | | +| **堆排序** | n log(n) | n log(n) | n log(n) | 1 | No | | +| **归并排序** | n log(n) | n log(n) | n log(n) | n | Yes | | +| **快速排序** | n log(n) | n log(n) | n^2 | log(n) | No | 在 in-place 版本下,内存复杂度通常是 O(log(n)) | +| **希尔排序** | n log(n) | 取决于差距序列 | n (log(n))^2 | 1 | No | | +| **计数排序** | n + r | n + r | n + r | n + r | Yes | r - 数组里最大的数 | +| **基数排序** | n \* k | n \* k | n \* k | n + k | Yes | k - 最长 key 的升序 | > ℹ️ A few more [projects](https://trekhleb.dev/projects/) and [articles](https://trekhleb.dev/blog/) about JavaScript and algorithms on [trekhleb.dev](https://trekhleb.dev) diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000000..e9926e029e --- /dev/null +++ b/examples/README.md @@ -0,0 +1,73 @@ +# 算法练习 + +- 阶乘函数 [factorial] +- 斐波那契数列 [fibonacci] +- 全局唯一标识符 + - [uuid] + - [guid] + - Twitter的雪花算法 [snowflake] +- LZ系列压缩算法 + - LZ系列压缩算法均为LZ77与LZ78的变种,在此基础上做了优化。 + - LZ77:LZSS、LZR、LZB、LZH; + - LZ78:LZW、LZC、LZT、LZMW、LZJ、LZFG。 + - 其中,LZSS与LZW为这两大阵容里名气最响亮的算法。LZSS是由Storer与Szymanski [2]改进了LZ77:增加最小匹配长度的限制,当最长匹配的长度小于该限制时,则不压缩输出,但仍然滑动窗口右移一个字符。Google开源的Snappy压缩算法库大体遵循LZSS的编码方案,在其基础上做了一些工程上的优化。 +- LRU +- 判断回文数 +- 最长回文子串 https://www.cnblogs.com/en-heng/p/3973679.html +- 去掉重复值(数组) +- 找出字符串中出现次数最多的字母 +- 求最大值、最小值 +- 验证是否为数组 + +Node.js大众点评爬虫 https://www.cnblogs.com/en-heng/p/5895207.html + +- lz77 算法 + - https://www.jb51.net/article/23024.htm + - https://www.jb51.net/article/120912.htm + +- 随机算法 random + - uuid + - 随机洗牌 knuth-shuffle + - http://caibaojian.com/js-random-array.html + - https://www.h5jun.com/post/array-shuffle.html + - http://caibaojian.com/get-random-element.html + - 5分钟现场撸代码——谈总结会抽奖程序 https://www.h5jun.com/post/luckey-draw-in-5-minutes.html + +- Twitter的雪花算法 snowflake + +重学前端 https://www.w3cplus.com/relearn-the-front-end-techniques.html + +排序算法 + +第三届360前端星计划在线作业题 +https://www.h5jun.com/post/75team-star-handlock.html + +用65行代码实现JavaScript动画序列播放 +https://www.h5jun.com/post/sixty-lines-of-code-animation.html + +为什么 [ ] 是 false 而 !![ ] 是 true +https://www.h5jun.com/post/why-false-why-true.html + +https://www.cnblogs.com/en-heng/category/582209.html +【十大经典数据挖掘算法】SVM系列 https://www.cnblogs.com/en-heng/p/5965438.html + +别人家的面试题:不可变数组快速范围求和 https://75team.com/post/range-sum-query-immutable.html +别人家的面试题:自然数拆分求最大乘积 https://75team.com/post/integer-break.html + +别人家的面试题:统计“1”的个数(续) https://75team.com/post/count_bits.html + +https://www.h5jun.com/post/html5-element-flowchart.html +HTML5 元素选择流程图 + +https://www.h5jun.com/post/multiply7.html 别人家的面试题:不用加减乘除,求整数的7倍 + +C4.5 +K-Means +SVM +Apriori +EM +PageRank +AdaBoost +kNN +Naïve Bayes +CART diff --git a/examples/factorial/README.md b/examples/factorial/README.md new file mode 100644 index 0000000000..13bbfea9da --- /dev/null +++ b/examples/factorial/README.md @@ -0,0 +1,9 @@ +# 阶乘函数 Factorial + +描述:一个正整数的阶乘是所有小于及等于该数的正整数的积,并且有`0`的阶乘为`1`。自然数`n`的阶乘写作`n!`。 + +阶乘函数是[递归(Haskell)函数](https://zh.wikibooks.org/zh/Haskell/%E9%80%92%E5%BD%92)典型示例 + +参考资料: + +- https://www.w3cplus.com/javascript/factorial-function-in-javascript.html diff --git a/examples/fibonacci/.circleci/config.yml b/examples/fibonacci/.circleci/config.yml new file mode 100644 index 0000000000..716a8f29b8 --- /dev/null +++ b/examples/fibonacci/.circleci/config.yml @@ -0,0 +1,39 @@ +# Javascript Node CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-javascript/ for more details +# +version: 2 +jobs: + build: + docker: + # specify the version you desire here + - image: circleci/node:8.11.1 + + # Specify service dependencies here if necessary + # CircleCI maintains a library of pre-built images + # documented at https://circleci.com/docs/2.0/circleci-images/ + # - image: circleci/mongo:3.4.4 + + working_directory: ~/repo + + steps: + - checkout + + # Download and cache dependencies + - restore_cache: + keys: + - v1-dependencies-{{ checksum "package.json" }} + # fallback to using the latest cache if no exact match is found + - v1-dependencies- + + - run: yarn install + + - save_cache: + paths: + - node_modules + key: v1-dependencies-{{ checksum "package.json" }} + + # run tests! + - run: yarn test + + diff --git a/examples/fibonacci/README.md b/examples/fibonacci/README.md new file mode 100644 index 0000000000..694d7816a8 --- /dev/null +++ b/examples/fibonacci/README.md @@ -0,0 +1,10 @@ +# 斐波那契数列 fibonacci + +

+ Build Status + Coverage Status +

+ +使用 JavaScript 尽可能快地来计算斐波那契数列。 + +from https://github.com/jskit/kit-fibonacci diff --git a/examples/fibonacci/__test__/fastfib.spec.js b/examples/fibonacci/__test__/fastfib.spec.js new file mode 100644 index 0000000000..6eb3b31145 --- /dev/null +++ b/examples/fibonacci/__test__/fastfib.spec.js @@ -0,0 +1,18 @@ +const assert = require('assert') +const fastfib = require('../lib/index') + +assert.equal(fastfib(0), 0) +assert.equal(fastfib(1), 1) +assert.equal(fastfib(2), 1) +assert.equal(fastfib(3), 2) +assert.equal(fastfib(4), 3) +assert.equal(fastfib(5), 5) +assert.equal(fastfib(6), 8) +assert.equal(fastfib(7), 13) +assert.equal(fastfib(8), 21) +assert.equal(fastfib(9), 34) +assert.equal(fastfib(10), 55) +assert.equal(fastfib(11), 89) +assert.equal(fastfib(12), 144) + +console.log('Test passed') diff --git a/examples/fibonacci/benchmark/index.js b/examples/fibonacci/benchmark/index.js new file mode 100644 index 0000000000..11d483900d --- /dev/null +++ b/examples/fibonacci/benchmark/index.js @@ -0,0 +1,30 @@ + +// https://www.npmjs.com/package/benchmark + +const assert = require('assert'); +const suite = new (require('benchmark')).Suite; +const recurse = require('../lib/recurse'); +const tail = require('../lib/tail'); +const iter = require('../lib/iter'); + +/* eslint new-parens: 0 */ +// const suite = new Suite + +/* eslint func-names: 0 */ +suite + .add('recurse', () => { recurse(20); }) + .add('tail', () => { tail(20); }) + .add('iter', () => { iter(20); }) + .on('complete', function () { + console.log('result: '); + // console.log(this) + this.forEach((result) => { + console.log(result.name, result.count, result.times.elapsed); + }); + assert.equal( + this.filter('fastest').map('name'), + 'iter', + 'expect iter to be the fastest', + ); + }) + .run(); diff --git a/examples/fibonacci/package.json b/examples/fibonacci/package.json new file mode 100644 index 0000000000..9a9de2393d --- /dev/null +++ b/examples/fibonacci/package.json @@ -0,0 +1,37 @@ +{ + "name": "kit-fibonacci", + "version": "1.0.2", + "description": "fastfib 使用 JavaScript 尽可能快地来计算斐波那契数列。", + "main": "lib/index.js", + "scripts": { + "prepublishOnly": "npm run lib", + "lib": "babel src -d lib", + "test": "node test/fastfib.spec.js && node benchmark" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jskit/kit-fibonacci.git" + }, + "keywords": [ + "fibonacci", + "fastfib", + "kitjs" + ], + "author": "cloudyan <1395093509@qq.com>", + "license": "MIT", + "bugs": { + "url": "https://github.com/jskit/kit-fibonacci/issues" + }, + "homepage": "https://github.com/jskit/kit-fibonacci#readme", + "dependencies": {}, + "devDependencies": { + "babel-core": "^6.26.0", + "babel-eslint": "^8.0.3", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-env": "^1.6.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-stage-2": "^6.24.1", + "benchmark": "^2.1.4" + } +} diff --git a/examples/fibonacci/src/index.js b/examples/fibonacci/src/index.js new file mode 100644 index 0000000000..48aff2e056 --- /dev/null +++ b/examples/fibonacci/src/index.js @@ -0,0 +1,5 @@ +// import recurse from './recurse' +// import tail from './tail' +import iter from './iter'; + +export default iter; diff --git a/examples/fibonacci/src/iter.js b/examples/fibonacci/src/iter.js new file mode 100644 index 0000000000..285526fb6a --- /dev/null +++ b/examples/fibonacci/src/iter.js @@ -0,0 +1,20 @@ + +/** + * 迭代方式来实现斐波那契数列 + * + * @param {number} n + * @returns + */ +function iter(n) { + let current = 0; + let next = 1; + /* eslint no-plusplus: 0 */ + for (let i = 0; i < n; i++) { + const swap = current; + current = next; + next = swap + next; + } + return current; +} + +export default iter; diff --git a/examples/fibonacci/src/recurse.js b/examples/fibonacci/src/recurse.js new file mode 100644 index 0000000000..59cb915353 --- /dev/null +++ b/examples/fibonacci/src/recurse.js @@ -0,0 +1,15 @@ + + +/** + * 递归方法实现斐波那契数列 + * + * @param {number} n + * @returns + */ +function recurse(n) { + if (n === 0) return 0; + if (n === 1) return 1; + return recurse(n - 1) + recurse(n - 2); +} + +export default recurse; diff --git a/examples/fibonacci/src/tail.js b/examples/fibonacci/src/tail.js new file mode 100644 index 0000000000..27dc02c051 --- /dev/null +++ b/examples/fibonacci/src/tail.js @@ -0,0 +1,25 @@ + +/** + * 尾递归优化 + * + * @param {number} n + * @param {number} current + * @param {number} next + * @returns + */ +function fib(n, current, next) { + if (n === 0) return current; + return fib(n - 1, next, current + next); +} + +/** + * 尾递归优化实现斐波那契数列 + * + * @param {number} n + * @returns + */ +function tail(n) { + return fib(n, 0, 1); +} + +export default tail; diff --git a/examples/fibonacci/ts/index.ts b/examples/fibonacci/ts/index.ts new file mode 100644 index 0000000000..48aff2e056 --- /dev/null +++ b/examples/fibonacci/ts/index.ts @@ -0,0 +1,5 @@ +// import recurse from './recurse' +// import tail from './tail' +import iter from './iter'; + +export default iter; diff --git a/examples/fibonacci/ts/iter.ts b/examples/fibonacci/ts/iter.ts new file mode 100644 index 0000000000..f7e547706e --- /dev/null +++ b/examples/fibonacci/ts/iter.ts @@ -0,0 +1,24 @@ + +/** + * 迭代方式来实现斐波那契数列 + * + * @param {number} n + * @returns {number} + */ +function iter(n: number): number { + let current = 0; + let next = 1; + /* eslint no-plusplus: 0 */ + for (let i = 0; i < n; i++) { + const swap = current; + current = next; + next = swap + next; + } + return current; +} + +// test +console.log(iter(5)) +console.log(iter(15)) + +export default iter; diff --git a/examples/fibonacci/ts/recurse.ts b/examples/fibonacci/ts/recurse.ts new file mode 100644 index 0000000000..1684d1b23f --- /dev/null +++ b/examples/fibonacci/ts/recurse.ts @@ -0,0 +1,14 @@ + +/** + * 递归方法实现斐波那契数列 + * + * @param {number} n + * @returns {*} + */ +function recurse(n: number): any { + if (n === 0) return 0; + if (n === 1) return 1; + return recurse(n - 1) + recurse(n - 2); +} + +export default recurse; diff --git a/examples/fibonacci/ts/tail.ts b/examples/fibonacci/ts/tail.ts new file mode 100644 index 0000000000..c1cfd7bfec --- /dev/null +++ b/examples/fibonacci/ts/tail.ts @@ -0,0 +1,25 @@ + +/** + * 尾递归优化 + * + * @param {number} n + * @param {number} current + * @param {number} next + * @returns {*} + */ +function fib(n: number, current: number, next: number): any { + if (n === 0) return current; + return fib(n - 1, next, current + next); +} + +/** + * 尾递归优化实现斐波那契数列 + * + * @param {number} n + * @returns + */ +function tail(n: number) { + return fib(n, 0, 1); +} + +export default tail; diff --git a/examples/fibonacci/ts/tempCodeRunnerFile.ts b/examples/fibonacci/ts/tempCodeRunnerFile.ts new file mode 100644 index 0000000000..45c3b5bfcd --- /dev/null +++ b/examples/fibonacci/ts/tempCodeRunnerFile.ts @@ -0,0 +1,22 @@ + +/** + * 迭代方式来实现斐波那契数列 + * + * @param {number} n + * @returns {number} + */ +function iter(n: number): number { + let current = 0; + let next = 1; + /* eslint no-plusplus: 0 */ + for (let i = 0; i < n; i++) { + const swap = current; + current = next; + next = swap + next; + } + return current; +} + +// test +console.log(iter(5)) +console.log(iter(15)) \ No newline at end of file diff --git a/examples/lz77/README.md b/examples/lz77/README.md new file mode 100644 index 0000000000..e1caaca1cd --- /dev/null +++ b/examples/lz77/README.md @@ -0,0 +1,21 @@ +# 数据压缩 lz77 算法 + +原理及实现 + +LZ77算法是采用字典做数据压缩的算法,由以色列的两位大神Jacob Ziv与Abraham Lempel在1977年发表的论文《A Universal Algorithm for Sequential Data Compression》中提出。 + +基于统计的数据压缩编码,比如Huffman编码,需要得到先验知识——信源的字符频率,然后进行压缩。但是在大多数情况下,这种先验知识是很难预先获得。因此,设计一种更为通用的数据压缩编码显得尤为重要。LZ77数据压缩算法应运而生,其核心思想:利用数据的**重复结构信息**来进行数据压缩。 + +如何描述重复结构信息,LZ77算法给出了更为确切的数学解释。首先,定义字符串S的长度为N,字符串S的子串Si,j, 1≤i,j≤N。对于前缀子串S1,j,记Lji为首字符Si的子串与首字符Sj+1的子串最大匹配的长度,即: + +``` +L_i^j = \max \{ l | S_{i,i+l-1} = S_{j+1,j+l} \} \quad \text{subject to} \quad l \le N-j +``` + +我们称字符串Sj+1,j+l匹配了字符串Si,i+l−1,且匹配长度为l。如图所示,存在两类情况: + +参考资料: + +- http://www.cnblogs.com/en-heng/p/4992916.html +- https://www.jb51.net/article/23024.htm +- https://www.jb51.net/article/120912.htm diff --git a/examples/lz78/README.md b/examples/lz78/README.md new file mode 100644 index 0000000000..0ab61d6fd0 --- /dev/null +++ b/examples/lz78/README.md @@ -0,0 +1,7 @@ +# 数据压缩 LZ78算法原理及实现 + +在提出基于滑动窗口的LZ77算法后,两位大神Jacob Ziv与Abraham Lempel于1978年在发表的论文 [1]中提出了LZ78算法;与LZ77算法不同的是LZ78算法使用动态树状词典维护历史字符串。 + +参考资料: + +- http://www.cnblogs.com/en-heng/p/6283282.html diff --git a/examples/uuid/README.md b/examples/uuid/README.md new file mode 100644 index 0000000000..dc5745d26d --- /dev/null +++ b/examples/uuid/README.md @@ -0,0 +1,19 @@ +# UUID + +UUID 就是 Universal Unique IDentifier 的缩写,它是一个128位,16字节的值,并确保在时间和空间上唯一。 +它是把硬件地址、时间以及随机数结合在一起,它保证对在同一时空中的所有机器都是唯一的。 + +通常平台会提供生成UUID的API。UUID按照开放软件基金会 (OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID (Globals Unique Identifiers)。 + +GUID(Globals Unique Identifiers 全局统一标识符)是微软对UUID这个标准的实现。是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成GUID的API。生成算法很有意思,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。GUID的唯一缺陷在于生成的结果串会比较大。 + +一个GUID为一个128位的整数(16字节),在使用唯一标识符的情况下,你可以在所有计算机和网络之间使用这一整数。GUID 的格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的字。例如:337c7f2b-7a34-4f50-9141-bab9e6478cc8 即为有效的 GUID 值。 + +世界上的任何两台计算机都不会生成重复的 GUID 值。GUID 主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。在 Windows 平台上,GUID 应用非常广泛:注册表、类及接口标识、数据库、甚至自动生成的机器名、目录名等。一个GUID可以在后台数据库中操作一个主键。 + +参考资料: + +- https://blog.csdn.net/forlong401/article/details/7580147 +- https://blog.csdn.net/yuanlianming663/article/details/1842267 +- https://www.cnblogs.com/pangguoming/p/7090906.html +- http://www.cnblogs.com/snandy/p/3261754.html diff --git a/examples/uuid/src/guid.js b/examples/uuid/src/guid.js new file mode 100644 index 0000000000..1569772c02 --- /dev/null +++ b/examples/uuid/src/guid.js @@ -0,0 +1,91 @@ +/*! +Math.uuid.js (v1.4) +http://www.broofa.com +mailto:robert@broofa.com + +Copyright (c) 2010 Robert Kieffer +Dual licensed under the MIT and GPL licenses. +*/ + +/* + * Generate a random uuid. + * + * USAGE: Math.uuid(length, radix) + * length - the desired number of characters + * radix - the number of allowable values for each character. + * + * EXAMPLES: + * // No arguments - returns RFC4122, version 4 ID + * >>> Math.uuid() + * "92329D39-6F5C-4520-ABFC-AAB64544E172" + * + * // One argument - returns ID of the specified length + * >>> Math.uuid(15) // 15 character ID (default base=62) + * "VcydxgltxrVZSTV" + * + * // Two arguments - returns ID of the specified length, and radix. (Radix must be <= 62) + * >>> Math.uuid(8, 2) // 8 character ID (base=2) + * "01001010" + * >>> Math.uuid(8, 10) // 8 character ID (base=10) + * "47473046" + * >>> Math.uuid(8, 16) // 8 character ID (base=16) + * "098F4D35" + */ + +// Private array of chars to use +var CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); + +Math.uuid = function (len, radix) { + var chars = CHARS, uuid = [], i; + radix = radix || chars.length; + + if (len) { + // Compact form + for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix]; + } else { + // rfc4122, version 4 form + var r; + + // rfc4122 requires these characters + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; + uuid[14] = '4'; + + // Fill in random data. At i==19 set the high bits of clock sequence as + // per rfc4122, sec. 4.1.5 + for (i = 0; i < 36; i++) { + if (!uuid[i]) { + r = 0 | Math.random()*16; + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; + } + } + } + + return uuid.join(''); +}; + +// A more performant, but slightly bulkier, RFC4122v4 solution. We boost performance +// by minimizing calls to random() +Math.uuidFast = function() { + var chars = CHARS, uuid = new Array(36), rnd=0, r; + for (var i = 0; i < 36; i++) { + if (i==8 || i==13 || i==18 || i==23) { + uuid[i] = '-'; + } else if (i==14) { + uuid[i] = '4'; + } else { + if (rnd <= 0x02) rnd = 0x2000000 + (Math.random()*0x1000000)|0; + r = rnd & 0xf; + rnd = rnd >> 4; + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; + } + } + return uuid.join(''); +}; + +// A more compact, but less performant, RFC4122v4 solution: +Math.uuidCompact = function() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }); +}; diff --git a/examples/uuid/src/uuid.js b/examples/uuid/src/uuid.js new file mode 100644 index 0000000000..bb09a144a1 --- /dev/null +++ b/examples/uuid/src/uuid.js @@ -0,0 +1,66 @@ +function uuid() { + var s = []; + var hexDigits = "0123456789abcdef"; + for (var i = 0; i < 36; i++) { + s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); + } + s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 + s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 + s[8] = s[13] = s[18] = s[23] = "-"; + + var uuid = s.join(""); + return uuid; +} + + +function guid() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }); +} + + +function guid() { + function S4() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1); + } + return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()); +} + +function uuid(len, radix) { + var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); + var uuid = [], i; + radix = radix || chars.length; + + if (len) { + // Compact form + for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix]; + } else { + // rfc4122, version 4 form + var r; + + // rfc4122 requires these characters + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; + uuid[14] = '4'; + + // Fill in random data. At i==19 set the high bits of clock sequence as + // per rfc4122, sec. 4.1.5 + for (i = 0; i < 36; i++) { + if (!uuid[i]) { + r = 0 | Math.random()*16; + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]; + } + } + } + + return uuid.join(''); +} + + +// 8 character ID (base=2) +uuid(8, 2) // "01001010" +// 8 character ID (base=10) +uuid(8, 10) // "47473046" +// 8 character ID (base=16) +uuid(8, 16) // "098F4D35" diff --git a/jest.config.js b/jest.config.js index 78568a1e94..4d62c9467a 100644 --- a/jest.config.js +++ b/jest.config.js @@ -13,7 +13,11 @@ module.exports = { coverageDirectory: './coverage/', // If the test path matches any of the patterns, it will be skipped. - testPathIgnorePatterns: ['/node_modules/'], + testPathIgnorePatterns: [ + '/node_modules/', + '/examples/', + '/temp/', + ], // If the file path matches any of the patterns, coverage information will be skipped. coveragePathIgnorePatterns: ['/node_modules/'], diff --git a/src/data-types/README.md b/src/data-types/README.md new file mode 100644 index 0000000000..ae5979cb4d --- /dev/null +++ b/src/data-types/README.md @@ -0,0 +1,72 @@ +# 数据类型 + +## 问题 + +- js 有几种基本数据类型?什么是原始值? +- 如何检查变量的数据类型? 参看 `@jskit/is` +- `+0 === -0`? +- javascript 的数据类型转换? + - 显式转换 + - 隐式转换 +- `NaN` 属于什么数据类型? +- 使用 `==` 符号,有哪些值会和 `null` `false` `0` 相等 +- 使用 `Array.prototype.includes()` 方法,是基于什么标准判断的?其他也包含判断的操作有哪些? +- javascript 中数字表示的范围? +- 怎么是安全的计算? +- 什么情况下选择使用位运算? +- null 和 undefined 的区别? + - undefined: + - 变量被声明了,但没有赋值时,就等于 undefined。 + - 调用函数时,应该提供的参数没有提供,该参数等于 undefined。 + - 对象没有赋值的属性,该属性的值为 undefined。 + - 函数没有返回值时,默认返回 undefined。 + - null: + - 作为函数的参数,表示该函数的参数不是对象。 + - 作为对象原型链的终点。 +- parseInt 深度学习 + + - https://www.cnblogs.com/jf-67/p/6481538.html + +- 什么是数据结构? +- 数据结构有哪些种? + +## 知识点 + +ECMAScript 标准定义了 8 种数据类型: + +- 7 种原始类型: + - Boolean + - Null + - Undefined + - Number + - String + - Symbol (ES6 新定义) + - BigInt (ES2020) +- Object + +除 Object 以外的所有类型都是不可变的(值本身无法被改变)。我们称这些类型的值为“原始值”。 + +**重要提示** 请熟读 MDN 参考文档[JavaScript 数据类型和数据结构 +](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures) + +扩展阅读: + +- JavaScript 有一个[内置对象的标准库](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects)。你可以查看参考来了解更多对象。 + +全局的对象( global objects )或称标准内置对象,不要和 "全局对象(global object)" 混淆。这里说的全局的对象是说在全局作用域里的对象。 + +"全局对象 (global object)” 是一个 Global 类的对象。可以在全局作用域里,用 this 访问(但只有在非严格模式下才可以,在严格模式下得到的是 undefined)。实际上,全局作用域包含了全局对象的属性,还有它可能继承来的属性。 + +- [JavaScript 中数字的底层表示](https://harttle.land/2018/06/29/javascript-numbers.html) +- [如何检查 JavaScript 变量类型?](https://harttle.land/2015/09/18/js-type-checking.html) +- [JavaScript 显式类型转换与隐式类型转换](https://harttle.land/2015/08/21/js-type-conv.html) + +## 测试练习 + +参见代码 + +参考资料: + +- [JavaScript 数据类型和数据结构](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures) +- [BigInt:JavaScript 中的任意精度整数](https://zhuanlan.zhihu.com/p/36330307) +- [Javascript 提案 BigInt 的一些坑](https://zhuanlan.zhihu.com/p/36385254) diff --git a/src/data-types/index.js b/src/data-types/index.js new file mode 100644 index 0000000000..cd935b08ec --- /dev/null +++ b/src/data-types/index.js @@ -0,0 +1,20 @@ + +/* eslint no-var: 0, no-unused-vars: 0, prefer-const: 0 */ +// number +var nine = 9; +const three = 3; +let two = 2; + +// boolean +const bool = false; + +// string +const city = 'shanghai'; + +// null +let nul = null; + +// undefined +let empty; + +// let bigInter = 23142314231412345663451234n; diff --git a/ts/data-types/README.md b/ts/data-types/README.md new file mode 100644 index 0000000000..e983af6ea2 --- /dev/null +++ b/ts/data-types/README.md @@ -0,0 +1,3 @@ +# 数据类型 + +此内容参见 [learn-typescript](https://github.com/cloudyan/learn-typescript) From 60266629f81981783a776e78e04dabec7287a604 Mon Sep 17 00:00:00 2001 From: jack <1395093509@qq.com> Date: Thu, 14 Feb 2019 21:48:45 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=AD=A6=E4=B9=A0=20=E9=93=BE=E8=A1=A8?= =?UTF-8?q?=E3=80=81=E9=98=9F=E5=88=97=E3=80=81=E6=A0=88=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E5=93=88=E5=B8=8C=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + examples/fibonacci/.circleci/config.yml | 39 ------------------- examples/fibonacci/__test__/fastfib.spec.js | 32 +++++++-------- examples/hash/README.md | 34 ++++++++++++++++ examples/hash/src/md5.js | 8 ++++ jest.config.js | 2 + .../doubly-linked-list/README.zh-CN.md | 4 +- .../hash-table/README.zh-CN.md | 28 +++++++++++-- src/data-structures/linked-list/LinkedList.js | 10 +++++ .../linked-list/README.zh-CN.md | 6 ++- 10 files changed, 102 insertions(+), 62 deletions(-) delete mode 100644 examples/fibonacci/.circleci/config.yml create mode 100644 examples/hash/README.md create mode 100644 examples/hash/src/md5.js diff --git a/.gitignore b/.gitignore index f46ad49b8e..d7f02cd242 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ coverage .DS_Store temp +tempCodeRunnerFile.js diff --git a/examples/fibonacci/.circleci/config.yml b/examples/fibonacci/.circleci/config.yml deleted file mode 100644 index 716a8f29b8..0000000000 --- a/examples/fibonacci/.circleci/config.yml +++ /dev/null @@ -1,39 +0,0 @@ -# Javascript Node CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-javascript/ for more details -# -version: 2 -jobs: - build: - docker: - # specify the version you desire here - - image: circleci/node:8.11.1 - - # Specify service dependencies here if necessary - # CircleCI maintains a library of pre-built images - # documented at https://circleci.com/docs/2.0/circleci-images/ - # - image: circleci/mongo:3.4.4 - - working_directory: ~/repo - - steps: - - checkout - - # Download and cache dependencies - - restore_cache: - keys: - - v1-dependencies-{{ checksum "package.json" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - - run: yarn install - - - save_cache: - paths: - - node_modules - key: v1-dependencies-{{ checksum "package.json" }} - - # run tests! - - run: yarn test - - diff --git a/examples/fibonacci/__test__/fastfib.spec.js b/examples/fibonacci/__test__/fastfib.spec.js index 6eb3b31145..e1ff4c99bc 100644 --- a/examples/fibonacci/__test__/fastfib.spec.js +++ b/examples/fibonacci/__test__/fastfib.spec.js @@ -1,18 +1,18 @@ -const assert = require('assert') -const fastfib = require('../lib/index') +const assert = require('assert'); +const fastfib = require('../lib/index'); -assert.equal(fastfib(0), 0) -assert.equal(fastfib(1), 1) -assert.equal(fastfib(2), 1) -assert.equal(fastfib(3), 2) -assert.equal(fastfib(4), 3) -assert.equal(fastfib(5), 5) -assert.equal(fastfib(6), 8) -assert.equal(fastfib(7), 13) -assert.equal(fastfib(8), 21) -assert.equal(fastfib(9), 34) -assert.equal(fastfib(10), 55) -assert.equal(fastfib(11), 89) -assert.equal(fastfib(12), 144) +assert.equal(fastfib(0), 0); +assert.equal(fastfib(1), 1); +assert.equal(fastfib(2), 1); +assert.equal(fastfib(3), 2); +assert.equal(fastfib(4), 3); +assert.equal(fastfib(5), 5); +assert.equal(fastfib(6), 8); +assert.equal(fastfib(7), 13); +assert.equal(fastfib(8), 21); +assert.equal(fastfib(9), 34); +assert.equal(fastfib(10), 55); +assert.equal(fastfib(11), 89); +assert.equal(fastfib(12), 144); -console.log('Test passed') +console.log('Test passed'); diff --git a/examples/hash/README.md b/examples/hash/README.md new file mode 100644 index 0000000000..db9f437281 --- /dev/null +++ b/examples/hash/README.md @@ -0,0 +1,34 @@ +# HASH 算法 + +常用 HASH 函数 + +- 直接取余法:f(x) = x mod maxM; maxM一般是不太接近 2^t 的一个质数。 +- 乘法取整法:f(x) = trunc((x/maxX)*maxlongit) mod maxM,主要用于实数。 +- 平方取中法:f(x) = (x*x div 1000 ) mod 1000000); 平方后取中间的,每位包含信息比较多。 + +散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位。 + +常用hash算法 + +- MD5 + - MD4(RFC 1320)是 MIT 的Ronald L. Rivest在 1990 年设计的,MD 是 Message Digest(消息摘要) 的缩写。它适用在32位字长的处理器上用高速软件实现——它是基于 32位操作数的位操作来实现的。 + - MD5(RFC 1321)是 Rivest 于1991年对MD4的改进版本。它对输入仍以512位分组,其输出是4个32位字的级联,与 MD4 相同。MD5比MD4来得复杂,并且速度较之要慢一点,但更安全,在抗分析和抗差分方面表现更好。 +- SHA 家族 + - SHA1是由NIST NSA设计为同DSA一起使用的,它对长度小于2^64的输入,产生长度为160bit的散列值,因此抗穷举(brute-force)性更好。SHA-1 设计时基于和MD4相同原理,并且模仿了该算法。 + +HASH 主要用于信息安全领域中加密算法,它把一些不同长度的信息转化成杂乱的128位的编码里,叫做HASH值. 也可以说,hash就是找到一种数据内容和数据存放地址之间的映射关系。Hash算法在信息安全方面的应用主要体现在以下的3个方面: + +- 文件校验 + - 我们比较熟悉的校验算法有奇偶校验和CRC校验,这2种校验并没有抗数据篡改的能力,它们一定程度上能检测并纠正数据传输中的信道误码,但却不能防止对数据的恶意破坏。 + - MD5 Hash算法的"数字指纹"特性,使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法,不少Unix系统有提供计算md5 checksum的命令。 +- 数字签名 + - Hash 算法也是现代密码体系中的一个重要组成部分。由于非对称算法的运算速度较慢,所以在数字签名协议中,单向散列函数扮演了一个重要的角色。对 Hash 值,又称"数字摘要"进行数字签名,在统计上可以认为与对文件本身进行数字签名是等效的。而且这样的协议还有其他的优点。 +- 鉴权协议 + - 鉴权协议又被称作"挑战--认证模式:在传输信道是可被侦听,但不可被篡改的情况下,这是一种简单而安全的方法。 + +参考资料: + +- [Hash(散列函数)](https://baike.baidu.com/item/Hash/390310) +- [MD5](https://baike.baidu.com/item/MD5) +- [SHA家族](https://baike.baidu.com/item/SHA%E5%AE%B6%E6%97%8F/9849595) +- [npm: md5](https://www.npmjs.com/package/md5) diff --git a/examples/hash/src/md5.js b/examples/hash/src/md5.js new file mode 100644 index 0000000000..de77dac700 --- /dev/null +++ b/examples/hash/src/md5.js @@ -0,0 +1,8 @@ + +// https://github.com/pvorb/node-md5 +// import md5 from 'md5'; + +// message -- `String`, `Buffer`, `Array` or `Uint8Array` +// returns `String` + +// md5(message) diff --git a/jest.config.js b/jest.config.js index 4d62c9467a..fefe565590 100644 --- a/jest.config.js +++ b/jest.config.js @@ -13,10 +13,12 @@ module.exports = { coverageDirectory: './coverage/', // If the test path matches any of the patterns, it will be skipped. + // https://jestjs.io/docs/zh-Hans/configuration#testpathignorepatterns-%E6%95%B0%E7%BB%84-string testPathIgnorePatterns: [ '/node_modules/', '/examples/', '/temp/', + // '/**/tempCodeRunnerFile.js', ], // If the file path matches any of the patterns, coverage information will be skipped. diff --git a/src/data-structures/doubly-linked-list/README.zh-CN.md b/src/data-structures/doubly-linked-list/README.zh-CN.md index 3e669f4c45..c6fe90de51 100644 --- a/src/data-structures/doubly-linked-list/README.zh-CN.md +++ b/src/data-structures/doubly-linked-list/README.zh-CN.md @@ -8,9 +8,7 @@ 两个节点链接允许在任一方向上遍历列表。 -在双向链表中进行添加或者删除节点时,需做的链接更改要比单向链表复杂得多。这种操作在单向链表中更简单高效,因为不需要关注一个节点(除第一个和最后一个节点以外的节点)的两个链接,而只需要关注一个链接即可。 - - +在双向链表中进行添加或者删除节点时,需做的链接更改要比单向链表复杂得多。这种操作在单向链表中更简单高效,因为不需要关注一个节点(除第一个和最后一个节点以外的节点)的两个链接,而只需要关注一个链接即可。 ## 基础操作的伪代码 diff --git a/src/data-structures/hash-table/README.zh-CN.md b/src/data-structures/hash-table/README.zh-CN.md index c53214aa88..f338205917 100644 --- a/src/data-structures/hash-table/README.zh-CN.md +++ b/src/data-structures/hash-table/README.zh-CN.md @@ -3,11 +3,33 @@ 在计算中, 一个 **哈希表(hash table 或hash map)** 是一种实现 *关联数组(associative array)* 的抽象数据类型, 该结构可以将 *键映射到值*。 -哈希表使用 *哈希函数/散列函数* 来计算一个值在数组或桶(buckets)中或槽(slots)中对应的索引,可使用该索引找到所需的值。 +哈希表使用 *哈希函数/散列函数* 来计算一个值在数组或桶(buckets)中或槽(slots)中对应的索引,可使用该索引找到所需的值。 -理想情况下,散列函数将为每个键分配给一个唯一的桶(bucket),但是大多数哈希表设计采用不完美的散列函数,这可能会导致"哈希冲突(hash collisions)",也就是散列函数为多个键(key)生成了相同的索引,这种碰撞必须 -以某种方式进行处理。 +## 伪代码 +### 计算 hash + +为简单起见,我们将只使用密钥中所有字符的字符代码和计算散列值。但也可以使用更复杂的方法,如多项式字符串哈希来减少碰撞次数: + +```text +hash = charCodeAt(0) * PRIME^(n-1) + charCodeAt(1) * PRIME^(n-2) + ... + charCodeAt(n-1) +``` + +其中 charCodeAt(i) 是键的第i个字符代码,n是键的长度,PRIME就是任何质数,比如31。 + +```text +Hash(key) + Pre: 输入任意长度 key + Post: 通过散列算法变换成固定长度的散列值输出(消息摘要) + hash ← Array.from(key).reduce( + (hashAccumulator, keySymbol) => (hashAccumulator + keySymbol.charCodeAt(0)), + 0, + ); + return hash % this.buckets.length; +end Hash +``` + +理想情况下,散列函数将为每个键分配给一个唯一的桶(bucket),但是大多数哈希表设计采用不完美的散列函数,这可能会导致"哈希冲突(hash collisions)",也就是散列函数为多个键(key)生成了相同的索引,这种碰撞必须以某种方式进行处理。 ![Hash Table](./images/hash-table.jpeg) diff --git a/src/data-structures/linked-list/LinkedList.js b/src/data-structures/linked-list/LinkedList.js index ba7d0e3ee1..4ef73fa802 100644 --- a/src/data-structures/linked-list/LinkedList.js +++ b/src/data-structures/linked-list/LinkedList.js @@ -234,6 +234,16 @@ export default class LinkedList { return nodes; } + /** + * @param {*[]} values - Array of values that need to be converted to linked list. + * @return {LinkedList} + */ + fromArray(values) { + values.forEach(value => this.append(value)); + + return this; + } + /** * @param {function} [callback] * @return {string} diff --git a/src/data-structures/linked-list/README.zh-CN.md b/src/data-structures/linked-list/README.zh-CN.md index f0b75121e7..8a88157c59 100644 --- a/src/data-structures/linked-list/README.zh-CN.md +++ b/src/data-structures/linked-list/README.zh-CN.md @@ -14,6 +14,10 @@ ## 基本操作的伪代码 +[伪代码格式](https://blog.csdn.net/ssisse/article/details/51501797) + +- 赋值用箭头“←” + ### 插入 ```text @@ -31,7 +35,7 @@ Add(value) end Add ``` -``` +```text Prepend(value) Pre: value is the value to add to the list Post: value has been placed at the head of the list From fe17b571ee24fbf346a5045735c9b76f25f79ecb Mon Sep 17 00:00:00 2001 From: jack <1395093509@qq.com> Date: Thu, 14 Feb 2019 21:49:33 +0800 Subject: [PATCH 3/8] add .eslintignore --- .eslintignore | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .eslintignore diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..3873dcfee2 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,10 @@ +node_modules +template +packages/test +temp +dist +scripts +lib +coverage +.eslintrc.js +tempCodeRunnerFile.js From 70356b0e4f1412e00345e9faf96eb803099efa81 Mon Sep 17 00:00:00 2001 From: jack <1395093509@qq.com> Date: Fri, 15 Feb 2019 16:29:27 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E5=AD=A6=E4=B9=A0=20=E5=A0=86=E5=92=8C?= =?UTF-8?q?=E4=BC=98=E5=85=88=E9=98=9F=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../doubly-linked-list/README.zh-CN.md | 4 ++ src/data-structures/hash-table/HashTable.js | 1 + .../hash-table/README.zh-CN.md | 13 +++++- src/data-structures/heap/Heap.js | 19 ++++---- src/data-structures/heap/README.zh-CN.md | 46 ++++++++++++++++++- .../linked-list/README.zh-CN.md | 20 ++++++++ .../priority-queue/README.zh-CN.md | 24 +++++++++- src/data-structures/queue/README.zh-CN.md | 9 +++- src/data-structures/stack/README.zh-CN.md | 14 +++++- 9 files changed, 134 insertions(+), 16 deletions(-) diff --git a/src/data-structures/doubly-linked-list/README.zh-CN.md b/src/data-structures/doubly-linked-list/README.zh-CN.md index c6fe90de51..4e75e6bf68 100644 --- a/src/data-structures/doubly-linked-list/README.zh-CN.md +++ b/src/data-structures/doubly-linked-list/README.zh-CN.md @@ -10,6 +10,10 @@ 在双向链表中进行添加或者删除节点时,需做的链接更改要比单向链表复杂得多。这种操作在单向链表中更简单高效,因为不需要关注一个节点(除第一个和最后一个节点以外的节点)的两个链接,而只需要关注一个链接即可。 +## 基本操作 + +同链表 + ## 基础操作的伪代码 ### 插入 diff --git a/src/data-structures/hash-table/HashTable.js b/src/data-structures/hash-table/HashTable.js index b8b523ea85..fa3218025c 100644 --- a/src/data-structures/hash-table/HashTable.js +++ b/src/data-structures/hash-table/HashTable.js @@ -35,6 +35,7 @@ export default class HashTable { // // where charCodeAt(i) is the i-th character code of the key, n is the length of the key and // PRIME is just any prime number like 31. + // 求和取余 const hash = Array.from(key).reduce( (hashAccumulator, keySymbol) => (hashAccumulator + keySymbol.charCodeAt(0)), 0, diff --git a/src/data-structures/hash-table/README.zh-CN.md b/src/data-structures/hash-table/README.zh-CN.md index f338205917..a26640f041 100644 --- a/src/data-structures/hash-table/README.zh-CN.md +++ b/src/data-structures/hash-table/README.zh-CN.md @@ -5,11 +5,20 @@ 哈希表使用 *哈希函数/散列函数* 来计算一个值在数组或桶(buckets)中或槽(slots)中对应的索引,可使用该索引找到所需的值。 +## 基本操作 + +- hash 计算 hash 值 +- set +- get +- delete +- has +- getKeys + ## 伪代码 ### 计算 hash -为简单起见,我们将只使用密钥中所有字符的字符代码和计算散列值。但也可以使用更复杂的方法,如多项式字符串哈希来减少碰撞次数: +为简单起见,我们将只使用密钥中所有字符的字符代码**求和取余**计算散列值。但也可以使用更复杂的方法,如多项式字符串哈希来减少碰撞次数: ```text hash = charCodeAt(0) * PRIME^(n-1) + charCodeAt(1) * PRIME^(n-2) + ... + charCodeAt(n-1) @@ -31,6 +40,8 @@ end Hash 理想情况下,散列函数将为每个键分配给一个唯一的桶(bucket),但是大多数哈希表设计采用不完美的散列函数,这可能会导致"哈希冲突(hash collisions)",也就是散列函数为多个键(key)生成了相同的索引,这种碰撞必须以某种方式进行处理。 +如果存在冲突则 `append` 处理,否则直接赋值 + ![Hash Table](./images/hash-table.jpeg) *Made with [okso.app](https://okso.app)* diff --git a/src/data-structures/heap/Heap.js b/src/data-structures/heap/Heap.js index 45dfcfa267..7006d87ff3 100644 --- a/src/data-structures/heap/Heap.js +++ b/src/data-structures/heap/Heap.js @@ -2,6 +2,7 @@ import Comparator from '../../utils/comparator/Comparator'; /** * Parent class for Min and Max Heaps. + * 这里的堆实际上是二叉堆(Binary Heap),其实也可定义k叉堆。 */ export default class Heap { /** @@ -36,7 +37,7 @@ export default class Heap { /** * @param {number} childIndex - * @return {number} + * @return {number} 向下取整 */ getParentIndex(childIndex) { return Math.floor((childIndex - 1) / 2); @@ -67,27 +68,27 @@ export default class Heap { } /** - * @param {number} parentIndex + * @param {number} childIndex * @return {*} */ - leftChild(parentIndex) { - return this.heapContainer[this.getLeftChildIndex(parentIndex)]; + parent(childIndex) { + return this.heapContainer[this.getParentIndex(childIndex)]; } /** * @param {number} parentIndex * @return {*} */ - rightChild(parentIndex) { - return this.heapContainer[this.getRightChildIndex(parentIndex)]; + leftChild(parentIndex) { + return this.heapContainer[this.getLeftChildIndex(parentIndex)]; } /** - * @param {number} childIndex + * @param {number} parentIndex * @return {*} */ - parent(childIndex) { - return this.heapContainer[this.getParentIndex(childIndex)]; + rightChild(parentIndex) { + return this.heapContainer[this.getRightChildIndex(parentIndex)]; } /** diff --git a/src/data-structures/heap/README.zh-CN.md b/src/data-structures/heap/README.zh-CN.md index 8ba42dfb05..3c462191f0 100644 --- a/src/data-structures/heap/README.zh-CN.md +++ b/src/data-structures/heap/README.zh-CN.md @@ -14,10 +14,54 @@ ![Array Representation](./images/array-representation.jpeg) +在堆“顶部”的没有父级节点的节点, 被称之为根节点。 -在堆“顶部”的没有父级节点的节点,被称之为根节点。 +## 基本操作 + +堆就是用数组实现的一棵完全二叉树(在时间和空间上很高效),堆是完全二叉树,索引值具有以下关系 + +```text + parent(index) + / \ +left(2*index+1) right(2*index+2) + +- 第 h 层第 n 个元素是 `2 ^ h + n` +- 索引:父计算子 + leftChildIndex 为 `parentIndex * 2 + 1` + rightChildIndex 为 `parentIndex * 2 + 2` +- 索引:子计算父 + parentIndex 为 `(childIndex - 1) / 2` 后向下取整 + +因为上面索引值的关系,这也就是为什么可以直接用数组来存储堆的原因。 +``` + +- 索引、父子元素等操作 + - getLeftChildIndex + - getRightChildIndex + - getParentIndex + - hasParent 通过索引值有效性来判断 + - hasLeftChild + - hasRightChild + - parent 通过索引值获取 + - leftChild + - rightChild +- swap 两个值交换位置 +- peek 仅仅读取最小值或最大值 +- poll 从堆中提取最小值或最大值 `O(1)` +- add 向堆中插入一个新元素 insert(value) + - buildHeap(array) 通过反复调用 `insert()` 方法将一个(无序)数组转换成一个堆。如果你足够聪明,你可以在 `O(n)` 时间内完成。 +- remove 删除堆元素 delete removeAtIndex(index) +- find search(value) +- isEmpty +- toString +- 原始操作,用于保证插入或删除节点以后使其符合堆的性质 + - heapifyUp 将新元素提升使其符合堆的性质 + - heapifyDown 使删除堆顶元素的堆再次成为堆 + - pairIsInCorrectOrder 检查堆元素的顺序是否正确 ## 参考 - [Wikipedia](https://en.wikipedia.org/wiki/Heap_(data_structure)) - [YouTube](https://www.youtube.com/watch?v=t0Cq6tVNRBA&index=5&t=0s&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) +- [数据结构之“堆”](http://www.cnblogs.com/Jason-Damon/archive/2012/04/18/2454649.html) +- [数据结构:堆(Heap)](https://www.jianshu.com/p/6b526aa481b1) diff --git a/src/data-structures/linked-list/README.zh-CN.md b/src/data-structures/linked-list/README.zh-CN.md index 8a88157c59..4d3ac595f2 100644 --- a/src/data-structures/linked-list/README.zh-CN.md +++ b/src/data-structures/linked-list/README.zh-CN.md @@ -12,6 +12,26 @@ *Made with [okso.app](https://okso.app)* +## 基本操作 + +- 插入 + - prepend + - append +- 搜索 + - find +- 删除 + - delete + - deleteHead + - deleteTail +- 辅助 + - toArray + - fromArray + - toString + - reverse +- 其他 + - 遍历 + - 反向遍历 + ## 基本操作的伪代码 [伪代码格式](https://blog.csdn.net/ssisse/article/details/51501797) diff --git a/src/data-structures/priority-queue/README.zh-CN.md b/src/data-structures/priority-queue/README.zh-CN.md index caffcd7136..9ce239df00 100644 --- a/src/data-structures/priority-queue/README.zh-CN.md +++ b/src/data-structures/priority-queue/README.zh-CN.md @@ -4,12 +4,32 @@ 在优先队列中, 低优先级的元素之前前面应该是高优先级的元素。 如果两个元素具有相同的优先级, 则根据它们在队列中的顺序是它们的出现顺序即可。 -优先队列虽通常用堆来实现,但它在概念上与堆不同。优先队列是一个抽象概念,就像“列表”或“图”这样的抽象概念一样; +优先队列虽通常用堆来实现, 但它在概念上与堆不同。优先队列是一个抽象概念, 就像“列表”或“图”这样的抽象概念一样; -正如列表可以用链表或数组实现一样,优先队列可以用堆或各种其他方法实现,例如无序数组。 +正如列表可以用链表或数组实现一样, 优先队列可以用堆或各种其他方法实现, 例如无序数组。 +## 基本操作 + +此处实现 inherit MinHeap,按优先级排序存储数据 + +- add +- remove +- changePriority +- findByValue +- hasValue +- comparePriority +- compareValue + +优先队列的作用是能保证每次取出的元素都是队列中权值最小的(Java的优先队列每次取最小元素,C++的优先队列每次取最大元素)。这里牵涉到了大小关系,元素大小的评判可以通过元素本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator,类似于C++的仿函数)。 + +优先队列的应用比较广泛,比如作业系统中的调度程序,当一个作业完成后,需要在所有等待调度的作业中选择一个优先级最高的作业来执行,并且也可以添加一个新的作业到作业的优先队列中。 + +问题: + +这里执行 poll 时,优先队列里存储的优先级并未删除,可以覆写处理 ## 参考 - [Wikipedia](https://en.wikipedia.org/wiki/Priority_queue) - [YouTube](https://www.youtube.com/watch?v=wptevk0bshY&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8&index=6) +- [深入理解Java PriorityQueue](http://www.cnblogs.com/CarpenterLee/p/5488070.html) diff --git a/src/data-structures/queue/README.zh-CN.md b/src/data-structures/queue/README.zh-CN.md index af608107d3..d8b846b77f 100644 --- a/src/data-structures/queue/README.zh-CN.md +++ b/src/data-structures/queue/README.zh-CN.md @@ -4,13 +4,20 @@ 队列基本操作有两种:入队和出队。从队列的后端位置添加实体,称为入队;从队列的前端位置移除实体,称为出队。 - 队列中元素先进先出 FIFO (first in, first out)的示意 ![Queue](./images/queue.jpeg) *Made with [okso.app](https://okso.app)* +## 基本操作 + +- peek 读取队首 value +- enqueue 队尾入队 +- dequeue 队首出队 +- toString +- isEmpty + ## 参考 - [Wikipedia](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)) diff --git a/src/data-structures/stack/README.zh-CN.md b/src/data-structures/stack/README.zh-CN.md index f00e3eab00..05133abfe2 100644 --- a/src/data-structures/stack/README.zh-CN.md +++ b/src/data-structures/stack/README.zh-CN.md @@ -2,8 +2,8 @@ 在计算机科学中, 一个 **栈(stack)** 是一种抽象数据类型,用作表示元素的集合,具有两种主要操作: -* **push**, 添加元素到栈的顶端(末尾); -* **pop**, 移除栈最顶端(末尾)的元素. +- **push**, 添加元素到栈的顶端(末尾); +- **pop**, 移除栈最顶端(末尾)的元素. 以上两种操作可以简单概括为“后进先出(LIFO = last in, first out)”。 @@ -17,6 +17,16 @@ *Made with [okso.app](https://okso.app)* +## 基本操作 + +- push +- pop +- peek +- 辅助 + - isEmpty + - toArray + - toString + ## 参考 - [Wikipedia](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) From 1800334debbcc480934142ed01c539f7a735baaa Mon Sep 17 00:00:00 2001 From: jack <1395093509@qq.com> Date: Sat, 16 Feb 2019 18:17:11 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.zh-CN.md | 33 +++++++++++++++++++++--- examples/README.md | 14 +++++++++++ stl/README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 stl/README.md diff --git a/README.zh-CN.md b/README.zh-CN.md index dba0515b22..259652184c 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,10 +1,8 @@ # JavaScript 算法与数据结构 -TypeScript 版本 +## TypeScript 版本 -参考 - -- https://github.com/loiane/javascript-datastructures-algorithms +参考 https://github.com/loiane/javascript-datastructures-algorithms [![CI](https://github.com/trekhleb/javascript-algorithms/workflows/CI/badge.svg)](https://github.com/trekhleb/javascript-algorithms/actions?query=workflow%3ACI+branch%3Amaster) [![codecov](https://codecov.io/gh/trekhleb/javascript-algorithms/branch/master/graph/badge.svg)](https://codecov.io/gh/trekhleb/javascript-algorithms) @@ -290,6 +288,7 @@ npm test -- 'playground' ### 数组排序算法的复杂性 +<<<<<<< HEAD | 名称 | 最优 | 平均 | 最坏 | 内存 | 稳定 | 备注 | | ------------ | :------: | :------------: | :----------: | :----: | :--: | ---------------------------------------------- | | **冒泡排序** | n | n^2 | n^2 | 1 | Yes | | @@ -303,3 +302,29 @@ npm test -- 'playground' | **基数排序** | n \* k | n \* k | n \* k | n + k | Yes | k - 最长 key 的升序 | > ℹ️ A few more [projects](https://trekhleb.dev/projects/) and [articles](https://trekhleb.dev/blog/) about JavaScript and algorithms on [trekhleb.dev](https://trekhleb.dev) +======= +| 名称 | 最优 | 平均 | 最坏 | 内存 | 稳定 | 备注 | +| --------------------- | :-------: | :-------: | :-----------: | :-------: | :-------: | --------------------- | +| **冒泡排序** | n | n^2 | n^2 | 1 | Yes | | +| **插入排序** | n | n^2 | n^2 | 1 | Yes | | +| **选择排序** | n^2 | n^2 | n^2 | 1 | No | | +| **堆排序** | n log(n) | n log(n) | n log(n) | 1 | No | | +| **归并排序** | n log(n) | n log(n) | n log(n) | n | Yes | | +| **快速排序** | n log(n) | n log(n) | n^2 | log(n) | No | 在 in-place 版本下,内存复杂度通常是 O(log(n)) | +| **希尔排序** | n log(n) | 取决于差距序列 | n (log(n))^2 | 1 | No | | +| **计数排序** | n + r | n + r | n + r | n + r | Yes | r - 数组里最大的数 | +| **基数排序** | n * k | n * k | n * k | n + k | Yes | k - 最长 key 的升序 | + +## 扩展学习 + +* TypeScript 版本 +* 算法可视化 + +参考资料 + +* https://github.com/loiane/javascript-datastructures-algorithms +* https://visualgo.net/zh +* https://coolshell.cn/articles/4671.html + * https://www.cs.usfca.edu/~galles/visualization/Algorithms.html + * https://www.cs.usfca.edu/~galles/visualization/source.html +>>>>>>> 5b541e4 (更新文档) diff --git a/examples/README.md b/examples/README.md index e9926e029e..c1b10b4cde 100644 --- a/examples/README.md +++ b/examples/README.md @@ -19,6 +19,20 @@ - 求最大值、最小值 - 验证是否为数组 +迷宫生成算法 https://zhuanlan.zhihu.com/p/47395955 +https://bost.ocks.org/mike/algorithms/#maze-generation +https://github.com/luobotang/maze +https://bost.ocks.org/mike/ + +Java程序员3面小米,被俩算法题难倒,微软员工6分钟解决,真丢脸 +https://zhuanlan.zhihu.com/p/38850888 + + +为什么算法这么难? https://zhuanlan.zhihu.com/p/25101438 + +FreeCodeCamp 高级算法题 - 字符串排列 https://zhuanlan.zhihu.com/p/30567628 +https://zhuanlan.zhihu.com/p/27659059 + Node.js大众点评爬虫 https://www.cnblogs.com/en-heng/p/5895207.html - lz77 算法 diff --git a/stl/README.md b/stl/README.md new file mode 100644 index 0000000000..e587803a81 --- /dev/null +++ b/stl/README.md @@ -0,0 +1,62 @@ +# STL + +STL 是“Standard Template Library”的缩写,中文译为“标准模板库”。STL 是 C++ 标准库的一部分,不用单独安装。 + +C++ 对模板(Template)支持得很好,STL 就是借助模板把常用的数据结构及其算法都实现了一遍,并且做到了数据结构和算法的分离。例如,vector 的底层为顺序表(数组),list 的底层为双向链表,deque 的底层为循环队列,set 的底层为红黑树,hash_set 的底层为哈希表。 + +STL 组件主要包括容器,迭代器、算法和仿函数。 + +js实现 + +使用 js 实现一套类似 C++的 STL 库。 + +参考 + +- [js-stl](https://github.com/cloudyan/js-stl) +- [The JavaScript STL (Standard Template Library)](http://webreference.com/programming/javascript/gr/column13/index.html) +- [Std Javascript Library](http://www.stdjs.com/) + +## STL 见解 + +### 容器 + +容器即用来存储并管理某类对象的集合。例如鱼缸是用来盛放金鱼的容器。 + +每一种容器都有其优点和缺点。为满足程序的各种需求,STL 准备了多种容器类型,容器可以是 arrays 或是 linked lists,或者每个元素有特别的键值。 + +### 迭代器 + +迭代器用于在一个对象群集的元素上进行遍历动作。对象群集可能是容器,也可能是容器的一部分。 + +迭代器的主要用途是为容器提供一组很小的公共接口。利用这个接口,某项操作可以行进至群集内的下一个元素。 + +每种容器都提供了各自的迭代器。迭代器了解该容器的内部结构,所以能够正确行进。迭代器的接口和一般指针类似。 + +### 算法 + +算法用来处理群集内的元素,可以出于不同目的搜寻、排序、修改、使用那些元素。所有容器的迭代器都提供一致的接口,通过迭代器的协助,算法程序可以用于任意容器。 + +STL 的一个特性是将数据和操作分离。数据由容器类别加以管理,操作则由可定制的算法定义。迭代器在两者之间充当“粘合剂”,以使算法可以和容器交互运作。 + +STL 的另一个特性即组件可以针对任意型别运作。“标准模板库”这一名称即表示“可接受任意型别”的模板,并且这些型别均可执行必要操作。 + +在 STL 中,容器又分为**序列式容器**和**关联式容器**两大类,而迭代器的功能主要是遍历容器内全部或部分元素的对象。迭代器可划分为 5 种类属,这 5 种类属归属两种类型:**双向迭代器**和**随机存取迭代器**。 + +SIL 中提供的算法包括搜寻、排序、复制、重新排序、修改、数值运算等。 + +仿函数 + +STL中大量运用了仿函数。仿函数具有泛型编程强大的威力,是纯粹抽象概念的例证。 + +STL基本结构 + +STL 是 C++ 通用库,由迭代器、算法、容器、仿函数、配接器和配置器(即内存配置器)组成。 +容器 + +STL 包含诸多容器类。容器类是可以包含其他对象的类,就像数组和队列堆栈等数据结构包含整数、小数、类等数据成员一样。STL 可以包含常见的向量类、链表类、双向队列类、集合类、图类等,每个类都是一种模板,这些模板可以包含各种类型的对象。 + +参考: + +- http://c.biancheng.net/view/1436.html +- https://github.com/CarpenterLee/JCFInternals/blob/master/markdown/0-Introduction.md +- https://github.com/LukeLin/js-stl From 6e9c16c840e6446b839c21ecc214f8f2d4556464 Mon Sep 17 00:00:00 2001 From: jack <1395093509@qq.com> Date: Sat, 16 Feb 2019 20:52:17 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E6=96=87=E6=A1=A3=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.zh-CN.md | 32 ++------- src/algorithms/math/bits/README.zh-CN.md | 12 +++- src/algorithms/math/bits/bitLength.js | 1 + src/algorithms/math/complex-number/README.md | 2 + .../math/euclidean-algorithm/README.md | 2 + src/algorithms/math/factorial/README.zh-CN.md | 7 +- src/algorithms/math/fast-powering/README.md | 2 + src/algorithms/math/fibonacci/README.zh-CN.md | 2 + .../math/fourier-transform/README.md | 2 + .../math/integer-partition/README.md | 20 +++--- src/algorithms/math/is-power-of-two/README.md | 2 + .../math/least-common-multiple/README.md | 28 ++++---- src/algorithms/math/liu-hui/README.md | 70 ++++++++++--------- src/algorithms/math/pascal-triangle/README.md | 40 ++++++----- src/algorithms/math/primality-test/README.md | 32 +++++---- src/algorithms/math/radian/README.md | 10 +-- .../math/sieve-of-eratosthenes/README.md | 8 ++- 17 files changed, 148 insertions(+), 124 deletions(-) diff --git a/README.zh-CN.md b/README.zh-CN.md index 259652184c..c0cbcb89c7 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -1,9 +1,5 @@ # JavaScript 算法与数据结构 -## TypeScript 版本 - -参考 https://github.com/loiane/javascript-datastructures-algorithms - [![CI](https://github.com/trekhleb/javascript-algorithms/workflows/CI/badge.svg)](https://github.com/trekhleb/javascript-algorithms/actions?query=workflow%3ACI+branch%3Amaster) [![codecov](https://codecov.io/gh/trekhleb/javascript-algorithms/branch/master/graph/badge.svg)](https://codecov.io/gh/trekhleb/javascript-algorithms) @@ -288,7 +284,6 @@ npm test -- 'playground' ### 数组排序算法的复杂性 -<<<<<<< HEAD | 名称 | 最优 | 平均 | 最坏 | 内存 | 稳定 | 备注 | | ------------ | :------: | :------------: | :----------: | :----: | :--: | ---------------------------------------------- | | **冒泡排序** | n | n^2 | n^2 | 1 | Yes | | @@ -302,29 +297,16 @@ npm test -- 'playground' | **基数排序** | n \* k | n \* k | n \* k | n + k | Yes | k - 最长 key 的升序 | > ℹ️ A few more [projects](https://trekhleb.dev/projects/) and [articles](https://trekhleb.dev/blog/) about JavaScript and algorithms on [trekhleb.dev](https://trekhleb.dev) -======= -| 名称 | 最优 | 平均 | 最坏 | 内存 | 稳定 | 备注 | -| --------------------- | :-------: | :-------: | :-----------: | :-------: | :-------: | --------------------- | -| **冒泡排序** | n | n^2 | n^2 | 1 | Yes | | -| **插入排序** | n | n^2 | n^2 | 1 | Yes | | -| **选择排序** | n^2 | n^2 | n^2 | 1 | No | | -| **堆排序** | n log(n) | n log(n) | n log(n) | 1 | No | | -| **归并排序** | n log(n) | n log(n) | n log(n) | n | Yes | | -| **快速排序** | n log(n) | n log(n) | n^2 | log(n) | No | 在 in-place 版本下,内存复杂度通常是 O(log(n)) | -| **希尔排序** | n log(n) | 取决于差距序列 | n (log(n))^2 | 1 | No | | -| **计数排序** | n + r | n + r | n + r | n + r | Yes | r - 数组里最大的数 | -| **基数排序** | n * k | n * k | n * k | n + k | Yes | k - 最长 key 的升序 | ## 扩展学习 -* TypeScript 版本 -* 算法可视化 +- [TypeScript 版本](https://github.com/loiane/javascript-datastructures-algorithms) +- [算法可视化](https://visualgo.net/zh) 参考资料 -* https://github.com/loiane/javascript-datastructures-algorithms -* https://visualgo.net/zh -* https://coolshell.cn/articles/4671.html - * https://www.cs.usfca.edu/~galles/visualization/Algorithms.html - * https://www.cs.usfca.edu/~galles/visualization/source.html ->>>>>>> 5b541e4 (更新文档) +- https://github.com/loiane/javascript-datastructures-algorithms +- https://visualgo.net/zh +- https://coolshell.cn/articles/4671.html + - https://www.cs.usfca.edu/~galles/visualization/Algorithms.html + - https://www.cs.usfca.edu/~galles/visualization/source.html diff --git a/src/algorithms/math/bits/README.zh-CN.md b/src/algorithms/math/bits/README.zh-CN.md index 9ec75069c6..e2cf56e2ab 100644 --- a/src/algorithms/math/bits/README.zh-CN.md +++ b/src/algorithms/math/bits/README.zh-CN.md @@ -4,6 +4,16 @@ _Read this in other languages:_ [français](README.fr-FR.md), [english](README.md) +### Bit 操控 + +- set +- get +- update +- clear +- 乘 +- 除 +- 变负 + #### Get Bit 该方法向右移动目标位到最右边,即位数组的第0个位置上。然后在该数上与形如 `0001`的二进制形式的数进行`AND`操作。这会清理掉除了目标位的所有其它位的数据。如果目标位是1,那么结果就是`1`,反之,结果是`0`; @@ -226,7 +236,7 @@ B = 6: 110 └──────┴────┴────┴─────────┴──────────┴─────────┴───────────┴───────────┘ ``` -> 查看[fullAdder.js](fullAdder.js)了解更多细节。 +> 查看[fullAdder.js](fullAdder.js)了解更多细节。 > 查看[Full Adder on YouTube](https://www.youtube.com/watch?v=wvJc9CZcvBc&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8). ## References diff --git a/src/algorithms/math/bits/bitLength.js b/src/algorithms/math/bits/bitLength.js index 0fc2727d0e..5d6eef98c8 100644 --- a/src/algorithms/math/bits/bitLength.js +++ b/src/algorithms/math/bits/bitLength.js @@ -1,5 +1,6 @@ /** * Return the number of bits used in the binary representation of the number. + * or number.toString(2).length * * @param {number} number * @return {number} diff --git a/src/algorithms/math/complex-number/README.md b/src/algorithms/math/complex-number/README.md index 7629aad3f0..16ff7e58e3 100644 --- a/src/algorithms/math/complex-number/README.md +++ b/src/algorithms/math/complex-number/README.md @@ -1,5 +1,7 @@ # Complex Number +复数 - 复数及其基本运算 + _Read this in other languages:_ [français](README.fr-FR.md). diff --git a/src/algorithms/math/euclidean-algorithm/README.md b/src/algorithms/math/euclidean-algorithm/README.md index 89af03b15e..751a46bbf6 100644 --- a/src/algorithms/math/euclidean-algorithm/README.md +++ b/src/algorithms/math/euclidean-algorithm/README.md @@ -1,5 +1,7 @@ # Euclidean algorithm +欧几里得算法 - 计算最大公约数 (GCD) + _Read this in other languages:_ [français](README.fr-FR.md). diff --git a/src/algorithms/math/factorial/README.zh-CN.md b/src/algorithms/math/factorial/README.zh-CN.md index 89bcff1ff2..88c4e4e735 100644 --- a/src/algorithms/math/factorial/README.zh-CN.md +++ b/src/algorithms/math/factorial/README.zh-CN.md @@ -6,7 +6,7 @@ 5! = 5 * 4 * 3 * 2 * 1 = 120 ``` -| n | n! | +| n | n! | | ----- | --------------------------: | | 0 | 1 | | 1 | 1 | @@ -25,3 +25,8 @@ | 14 | 87 178 291 200 | | 15 | 1 307 674 368 000 | +实现方式 + +- 迭代方式 iter +- 递归方式 recurse +- 尾递归优化 tail diff --git a/src/algorithms/math/fast-powering/README.md b/src/algorithms/math/fast-powering/README.md index 2c2619d2ef..8fe837e5ad 100644 --- a/src/algorithms/math/fast-powering/README.md +++ b/src/algorithms/math/fast-powering/README.md @@ -1,5 +1,7 @@ # Fast Powering Algorithm +快速算次方 + _Read this in other languages:_ [français](README.fr-FR.md). diff --git a/src/algorithms/math/fibonacci/README.zh-CN.md b/src/algorithms/math/fibonacci/README.zh-CN.md index 20378000d4..4ef502f6db 100644 --- a/src/algorithms/math/fibonacci/README.zh-CN.md +++ b/src/algorithms/math/fibonacci/README.zh-CN.md @@ -1,5 +1,7 @@ # 斐波那契数 +斐波那契数 - `经典` 和 `闭式` 版本 + _Read this in other languages:_ [français](README.fr-FR.md), [english](README.md), diff --git a/src/algorithms/math/fourier-transform/README.md b/src/algorithms/math/fourier-transform/README.md index f7969ddd5c..a8ca258600 100644 --- a/src/algorithms/math/fourier-transform/README.md +++ b/src/algorithms/math/fourier-transform/README.md @@ -3,6 +3,8 @@ _Read this in other languages:_ [français](README.fr-FR.md). +离散傅里叶变换 - 把时间信号解析成构成它的频率 + ## Definitions The **Fourier Transform** (**FT**) decomposes a function of time (a signal) into diff --git a/src/algorithms/math/integer-partition/README.md b/src/algorithms/math/integer-partition/README.md index 6023e1505a..1a14ff0c1f 100644 --- a/src/algorithms/math/integer-partition/README.md +++ b/src/algorithms/math/integer-partition/README.md @@ -1,11 +1,13 @@ # Integer Partition -In number theory and combinatorics, a partition of a positive -integer `n`, also called an **integer partition**, is a way of -writing `n` as a sum of positive integers. +整数拆分 -Two sums that differ only in the order of their summands are -considered the same partition. For example, `4` can be partitioned +In number theory and combinatorics, a partition of a positive +integer `n`, also called an **integer partition**, is a way of +writing `n` as a sum of positive integers. + +Two sums that differ only in the order of their summands are +considered the same partition. For example, `4` can be partitioned in five distinct ways: ``` @@ -17,13 +19,13 @@ in five distinct ways: ``` The order-dependent composition `1 + 3` is the same partition -as `3 + 1`, while the two distinct -compositions `1 + 2 + 1` and `1 + 1 + 2` represent the same +as `3 + 1`, while the two distinct +compositions `1 + 2 + 1` and `1 + 1 + 2` represent the same partition `2 + 1 + 1`. Young diagrams associated to the partitions of the positive -integers `1` through `8`. They are arranged so that images -under the reflection about the main diagonal of the square +integers `1` through `8`. They are arranged so that images +under the reflection about the main diagonal of the square are conjugate partitions. ![Integer Partition](https://upload.wikimedia.org/wikipedia/commons/d/d8/Ferrer_partitioning_diagrams.svg) diff --git a/src/algorithms/math/is-power-of-two/README.md b/src/algorithms/math/is-power-of-two/README.md index 6ed1e92568..02bc92334a 100644 --- a/src/algorithms/math/is-power-of-two/README.md +++ b/src/algorithms/math/is-power-of-two/README.md @@ -1,5 +1,7 @@ # Is a power of two +判断 2 次方数 - 检查数字是否为 2 的幂 (原生和按位算法) + Given a positive integer, write a function to find if it is a power of two or not. diff --git a/src/algorithms/math/least-common-multiple/README.md b/src/algorithms/math/least-common-multiple/README.md index 3e49af9a5f..abbab9d5d6 100644 --- a/src/algorithms/math/least-common-multiple/README.md +++ b/src/algorithms/math/least-common-multiple/README.md @@ -1,11 +1,13 @@ # Least common multiple -In arithmetic and number theory, the least common multiple, -lowest common multiple, or smallest common multiple of -two integers `a` and `b`, usually denoted by `LCM(a, b)`, is -the smallest positive integer that is divisible by -both `a` and `b`. Since division of integers by zero is -undefined, this definition has meaning only if `a` and `b` are +最小公倍数 (LCM) + +In arithmetic and number theory, the least common multiple, +lowest common multiple, or smallest common multiple of +two integers `a` and `b`, usually denoted by `LCM(a, b)`, is +the smallest positive integer that is divisible by +both `a` and `b`. Since division of integers by zero is +undefined, this definition has meaning only if `a` and `b` are both different from zero. However, some authors define `lcm(a,0)` as `0` for all `a`, which is the result of taking the `lcm` to be the least upper bound in the lattice of divisibility. @@ -26,20 +28,20 @@ and the multiples of `6` are: 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, ... ``` -Common multiples of `4` and `6` are simply the numbers +Common multiples of `4` and `6` are simply the numbers that are in both lists: ``` 12, 24, 36, 48, 60, 72, .... ``` -So, from this list of the first few common multiples of +So, from this list of the first few common multiples of the numbers `4` and `6`, their least common multiple is `12`. ## Computing the least common multiple -The following formula reduces the problem of computing the -least common multiple to the problem of computing the greatest +The following formula reduces the problem of computing the +least common multiple to the problem of computing the greatest common divisor (GCD), also known as the greatest common factor: ``` @@ -48,11 +50,11 @@ lcm(a, b) = |a * b| / gcd(a, b) ![LCM](https://upload.wikimedia.org/wikipedia/commons/c/c9/Symmetrical_5-set_Venn_diagram_LCM_2_3_4_5_7.svg) -A Venn diagram showing the least common multiples of -combinations of `2`, `3`, `4`, `5` and `7` (`6` is skipped as +A Venn diagram showing the least common multiples of +combinations of `2`, `3`, `4`, `5` and `7` (`6` is skipped as it is `2 × 3`, both of which are already represented). -For example, a card game which requires its cards to be +For example, a card game which requires its cards to be divided equally among up to `5` players requires at least `60` cards, the number at the intersection of the `2`, `3`, `4` and `5` sets, but not the `7` set. diff --git a/src/algorithms/math/liu-hui/README.md b/src/algorithms/math/liu-hui/README.md index c53257f8dd..d2346f8a7d 100644 --- a/src/algorithms/math/liu-hui/README.md +++ b/src/algorithms/math/liu-hui/README.md @@ -1,66 +1,68 @@ # Liu Hui's π Algorithm +割圆术 - 基于 N-gons 的近似 π 计算 + Liu Hui remarked in his commentary to The Nine Chapters on the Mathematical Art, -that the ratio of the circumference of an inscribed hexagon to the diameter of -the circle was `three`, hence `π` must be greater than three. He went on to provide -a detailed step-by-step description of an iterative algorithm to calculate `π` to -any required accuracy based on bisecting polygons; he calculated `π` to -between `3.141024` and `3.142708` with a 96-gon; he suggested that `3.14` was -a good enough approximation, and expressed `π` as `157/50`; he admitted that -this number was a bit small. Later he invented an ingenious quick method to -improve on it, and obtained `π ≈ 3.1416` with only a 96-gon, with an accuracy -comparable to that from a 1536-gon. His most important contribution in this +that the ratio of the circumference of an inscribed hexagon to the diameter of +the circle was `three`, hence `π` must be greater than three. He went on to provide +a detailed step-by-step description of an iterative algorithm to calculate `π` to +any required accuracy based on bisecting polygons; he calculated `π` to +between `3.141024` and `3.142708` with a 96-gon; he suggested that `3.14` was +a good enough approximation, and expressed `π` as `157/50`; he admitted that +this number was a bit small. Later he invented an ingenious quick method to +improve on it, and obtained `π ≈ 3.1416` with only a 96-gon, with an accuracy +comparable to that from a 1536-gon. His most important contribution in this area was his simple iterative `π` algorithm. ## Area of a circle Liu Hui argued: -> Multiply one side of a hexagon by the radius (of its -circumcircle), then multiply this by three, to yield the -area of a dodecagon; if we cut a hexagon into a -dodecagon, multiply its side by its radius, then again -multiply by six, we get the area of a 24-gon; the finer -we cut, the smaller the loss with respect to the area -of circle, thus with further cut after cut, the area of -the resulting polygon will coincide and become one with +> Multiply one side of a hexagon by the radius (of its +circumcircle), then multiply this by three, to yield the +area of a dodecagon; if we cut a hexagon into a +dodecagon, multiply its side by its radius, then again +multiply by six, we get the area of a 24-gon; the finer +we cut, the smaller the loss with respect to the area +of circle, thus with further cut after cut, the area of +the resulting polygon will coincide and become one with the circle; there will be no loss ![Liu Hui](https://upload.wikimedia.org/wikipedia/commons/6/69/Cutcircle2.svg) Liu Hui's method of calculating the area of a circle. -Further, Liu Hui proved that the area of a circle is half of its circumference +Further, Liu Hui proved that the area of a circle is half of its circumference multiplied by its radius. He said: -> Between a polygon and a circle, there is excess radius. Multiply the excess -radius by a side of the polygon. The resulting area exceeds the boundary of +> Between a polygon and a circle, there is excess radius. Multiply the excess +radius by a side of the polygon. The resulting area exceeds the boundary of the circle -In the diagram `d = excess radius`. Multiplying `d` by one side results in -oblong `ABCD` which exceeds the boundary of the circle. If a side of the polygon -is small (i.e. there is a very large number of sides), then the excess radius +In the diagram `d = excess radius`. Multiplying `d` by one side results in +oblong `ABCD` which exceeds the boundary of the circle. If a side of the polygon +is small (i.e. there is a very large number of sides), then the excess radius will be small, hence excess area will be small. -> Multiply the side of a polygon by its radius, and the area doubles; +> Multiply the side of a polygon by its radius, and the area doubles; hence multiply half the circumference by the radius to yield the area of circle. ![Liu Hui](https://upload.wikimedia.org/wikipedia/commons/9/95/Cutcircle.svg) -The area within a circle is equal to the radius multiplied by half the +The area within a circle is equal to the radius multiplied by half the circumference, or `A = r x C/2 = r x r x π`. ## Iterative algorithm -Liu Hui began with an inscribed hexagon. Let `M` be the length of one side `AB` of +Liu Hui began with an inscribed hexagon. Let `M` be the length of one side `AB` of hexagon, `r` is the radius of circle. ![Liu Hui](https://upload.wikimedia.org/wikipedia/commons/4/46/Liuhui_geyuanshu.svg) -Bisect `AB` with line `OPC`, `AC` becomes one side of dodecagon (12-gon), let +Bisect `AB` with line `OPC`, `AC` becomes one side of dodecagon (12-gon), let its length be `m`. Let the length of `PC` be `j` and the length of `OP` be `G`. -`AOP`, `APC` are two right angle triangles. Liu Hui used +`AOP`, `APC` are two right angle triangles. Liu Hui used the [Gou Gu](https://en.wikipedia.org/wiki/Pythagorean_theorem) (Pythagorean theorem) theorem repetitively: @@ -79,12 +81,12 @@ theorem repetitively: ![](https://wikimedia.org/api/rest_v1/media/math/render/svg/3ffeafe88d2983b364ad3442746063e3207fe842) -From here, there is now a technique to determine `m` from `M`, which gives the -side length for a polygon with twice the number of edges. Starting with a -hexagon, Liu Hui could determine the side length of a dodecagon using this -formula. Then continue repetitively to determine the side length of a -24-gon given the side length of a dodecagon. He could do this recursively as -many times as necessary. Knowing how to determine the area of these polygons, +From here, there is now a technique to determine `m` from `M`, which gives the +side length for a polygon with twice the number of edges. Starting with a +hexagon, Liu Hui could determine the side length of a dodecagon using this +formula. Then continue repetitively to determine the side length of a +24-gon given the side length of a dodecagon. He could do this recursively as +many times as necessary. Knowing how to determine the area of these polygons, Liu Hui could then approximate `π`. ## References diff --git a/src/algorithms/math/pascal-triangle/README.md b/src/algorithms/math/pascal-triangle/README.md index ff5075414c..ecead203bb 100644 --- a/src/algorithms/math/pascal-triangle/README.md +++ b/src/algorithms/math/pascal-triangle/README.md @@ -1,47 +1,49 @@ # Pascal's Triangle -In mathematics, **Pascal's triangle** is a triangular array of +杨辉三角形 + +In mathematics, **Pascal's triangle** is a triangular array of the [binomial coefficients](https://en.wikipedia.org/wiki/Binomial_coefficient). -The rows of Pascal's triangle are conventionally enumerated -starting with row `n = 0` at the top (the `0th` row). The -entries in each row are numbered from the left beginning -with `k = 0` and are usually staggered relative to the +The rows of Pascal's triangle are conventionally enumerated +starting with row `n = 0` at the top (the `0th` row). The +entries in each row are numbered from the left beginning +with `k = 0` and are usually staggered relative to the numbers in the adjacent rows. The triangle may be constructed -in the following manner: In row `0` (the topmost row), there +in the following manner: In row `0` (the topmost row), there is a unique nonzero entry `1`. Each entry of each subsequent -row is constructed by adding the number above and to the -left with the number above and to the right, treating blank -entries as `0`. For example, the initial number in the +row is constructed by adding the number above and to the +left with the number above and to the right, treating blank +entries as `0`. For example, the initial number in the first (or any other) row is `1` (the sum of `0` and `1`), -whereas the numbers `1` and `3` in the third row are added +whereas the numbers `1` and `3` in the third row are added to produce the number `4` in the fourth row. ![Pascal's Triangle](https://upload.wikimedia.org/wikipedia/commons/0/0d/PascalTriangleAnimated2.gif) ## Formula -The entry in the `nth` row and `kth` column of Pascal's +The entry in the `nth` row and `kth` column of Pascal's triangle is denoted ![Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/206415d3742167e319b2e52c2ca7563b799abad7). -For example, the unique nonzero entry in the topmost +For example, the unique nonzero entry in the topmost row is ![Formula example](https://wikimedia.org/api/rest_v1/media/math/render/svg/b7e35f86368d5978b46c07fd6dddca86bd6e635c). -With this notation, the construction of the previous +With this notation, the construction of the previous paragraph may be written as follows: ![Formula](https://wikimedia.org/api/rest_v1/media/math/render/svg/203b128a098e18cbb8cf36d004bd7282b28461bf) -for any non-negative integer `n` and any +for any non-negative integer `n` and any integer `k` between `0` and `n`, inclusive. ![Binomial Coefficient](https://wikimedia.org/api/rest_v1/media/math/render/svg/a2457a7ef3c77831e34e06a1fe17a80b84a03181) ## Calculating triangle entries in O(n) time -We know that `i`-th entry in a line number `lineNumber` is -Binomial Coefficient `C(lineNumber, i)` and all lines start -with value `1`. The idea is to -calculate `C(lineNumber, i)` using `C(lineNumber, i-1)`. It +We know that `i`-th entry in a line number `lineNumber` is +Binomial Coefficient `C(lineNumber, i)` and all lines start +with value `1`. The idea is to +calculate `C(lineNumber, i)` using `C(lineNumber, i-1)`. It can be calculated in `O(1)` time using the following: ``` @@ -55,7 +57,7 @@ We can derive following expression from above two expressions: C(lineNumber, i) = C(lineNumber, i - 1) * (lineNumber - i + 1) / i ``` -So `C(lineNumber, i)` can be calculated +So `C(lineNumber, i)` can be calculated from `C(lineNumber, i - 1)` in `O(1)` time. ## References diff --git a/src/algorithms/math/primality-test/README.md b/src/algorithms/math/primality-test/README.md index 8a9852dc31..bc5914301d 100644 --- a/src/algorithms/math/primality-test/README.md +++ b/src/algorithms/math/primality-test/README.md @@ -1,23 +1,25 @@ # Primality Test -A **prime number** (or a **prime**) is a natural number greater than `1` that -cannot be formed by multiplying two smaller natural numbers. A natural number -greater than `1` that is not prime is called a composite number. For -example, `5` is prime because the only ways of writing it as a -product, `1 × 5` or `5 × 1`, involve `5` itself. However, `6` is -composite because it is the product of two numbers `(2 × 3)` that are -both smaller than `6`. +素数检测 (排除法) + +A **prime number** (or a **prime**) is a natural number greater than `1` that +cannot be formed by multiplying two smaller natural numbers. A natural number +greater than `1` that is not prime is called a composite number. For +example, `5` is prime because the only ways of writing it as a +product, `1 × 5` or `5 × 1`, involve `5` itself. However, `6` is +composite because it is the product of two numbers `(2 × 3)` that are +both smaller than `6`. ![Prime Numbers](https://upload.wikimedia.org/wikipedia/commons/f/f0/Primes-vs-composites.svg) -A **primality test** is an algorithm for determining whether an input -number is prime. Among other fields of mathematics, it is used -for cryptography. Unlike integer factorization, primality tests -do not generally give prime factors, only stating whether the -input number is prime or not. Factorization is thought to be -a computationally difficult problem, whereas primality testing -is comparatively easy (its running time is polynomial in the -size of the input). +A **primality test** is an algorithm for determining whether an input +number is prime. Among other fields of mathematics, it is used +for cryptography. Unlike integer factorization, primality tests +do not generally give prime factors, only stating whether the +input number is prime or not. Factorization is thought to be +a computationally difficult problem, whereas primality testing +is comparatively easy (its running time is polynomial in the +size of the input). ## References diff --git a/src/algorithms/math/radian/README.md b/src/algorithms/math/radian/README.md index 2de4655e7d..7d5ffcc421 100644 --- a/src/algorithms/math/radian/README.md +++ b/src/algorithms/math/radian/README.md @@ -1,17 +1,19 @@ # Radian -The **radian** (symbol **rad**) is the unit for measuring angles, and is the +弧度和角 - 弧度与角的相互转换 + +The **radian** (symbol **rad**) is the unit for measuring angles, and is the standard unit of angular measure used in many areas of mathematics. -The length of an arc of a unit circle is numerically equal to the measurement +The length of an arc of a unit circle is numerically equal to the measurement in radians of the angle that it subtends; one radian is just under `57.3` degrees. -An arc of a circle with the same length as the radius of that circle subtends an +An arc of a circle with the same length as the radius of that circle subtends an angle of `1 radian`. The circumference subtends an angle of `2π radians`. ![Radian](https://upload.wikimedia.org/wikipedia/commons/4/4e/Circle_radians.gif) -A complete revolution is 2π radians (shown here with a circle of radius one and +A complete revolution is 2π radians (shown here with a circle of radius one and thus circumference `2π`). ![2 pi Radian](https://upload.wikimedia.org/wikipedia/commons/6/67/2pi-unrolled.gif) diff --git a/src/algorithms/math/sieve-of-eratosthenes/README.md b/src/algorithms/math/sieve-of-eratosthenes/README.md index 876379a006..76a8f7a2da 100644 --- a/src/algorithms/math/sieve-of-eratosthenes/README.md +++ b/src/algorithms/math/sieve-of-eratosthenes/README.md @@ -1,5 +1,7 @@ # Sieve of Eratosthenes +素数筛 - 查找任意给定范围内的所有素数 + The Sieve of Eratosthenes is an algorithm for finding all prime numbers up to some limit `n`. It is attributed to Eratosthenes of Cyrene, an ancient Greek mathematician. @@ -12,11 +14,11 @@ It is attributed to Eratosthenes of Cyrene, an ancient Greek mathematician. 4. Mark as `false` all the multiples of `p` (that is, positions `2 * p`, `3 * p`, `4 * p`... until you reach the end of the array) 5. Find the first position greater than `p` that is `true` in the array. If there is no such position, stop. Otherwise, let `p` equal this new number (which is the next prime), and repeat from step 4 -When the algorithm terminates, the numbers remaining `true` in the array are all +When the algorithm terminates, the numbers remaining `true` in the array are all the primes below `n`. -An improvement of this algorithm is, in step 4, start marking multiples -of `p` from `p * p`, and not from `2 * p`. The reason why this works is because, +An improvement of this algorithm is, in step 4, start marking multiples +of `p` from `p * p`, and not from `2 * p`. The reason why this works is because, at that point, smaller multiples of `p` will have already been marked `false`. ## Example From 01451b149cdc0f7bbd60726a5f4441e2ccf0718b Mon Sep 17 00:00:00 2001 From: jack <1395093509@qq.com> Date: Fri, 22 Feb 2019 13:32:18 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E5=AD=A6=E4=B9=A0=20hash?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.zh-CN.md | 1 + examples/README.md | 3 ++ examples/hash/README.md | 3 ++ examples/uuid/README.md | 17 +++++++++++ .../hash-table/README.zh-CN.md | 1 + src/data-structures/linked-list/LinkedList.js | 10 ------- .../linked-list/README.zh-CN.md | 6 ++++ src/data-types/index.js | 1 - ts/data-types/index.ts | 30 +++++++++++++++++++ 9 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 ts/data-types/index.ts diff --git a/README.zh-CN.md b/README.zh-CN.md index c0cbcb89c7..eb0976917c 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -310,3 +310,4 @@ npm test -- 'playground' - https://coolshell.cn/articles/4671.html - https://www.cs.usfca.edu/~galles/visualization/Algorithms.html - https://www.cs.usfca.edu/~galles/visualization/source.html + - [常用数据结构对比及其应用场景](https://www.jianshu.com/p/ec17d738327f) diff --git a/examples/README.md b/examples/README.md index c1b10b4cde..a24e7b4116 100644 --- a/examples/README.md +++ b/examples/README.md @@ -27,6 +27,9 @@ https://bost.ocks.org/mike/ Java程序员3面小米,被俩算法题难倒,微软员工6分钟解决,真丢脸 https://zhuanlan.zhihu.com/p/38850888 +各种算法题等 +https://blog.csdn.net/v_JULY_v + 为什么算法这么难? https://zhuanlan.zhihu.com/p/25101438 diff --git a/examples/hash/README.md b/examples/hash/README.md index db9f437281..ee2e8be1cb 100644 --- a/examples/hash/README.md +++ b/examples/hash/README.md @@ -32,3 +32,6 @@ HASH 主要用于信息安全领域中加密算法,它把一些不同长度的 - [MD5](https://baike.baidu.com/item/MD5) - [SHA家族](https://baike.baidu.com/item/SHA%E5%AE%B6%E6%97%8F/9849595) - [npm: md5](https://www.npmjs.com/package/md5) +- [常见hash算法的原理](http://www.cnblogs.com/zhoug2020/p/6984191.html) +- [转 从头到尾彻底解析Hash表算法](https://www.cnblogs.com/dancheblog/p/3512284.html) +- [Hash 函数的常用算法和应用领域](http://www.cnblogs.com/qianxun/archive/2011/07/03/2096773.html) diff --git a/examples/uuid/README.md b/examples/uuid/README.md index dc5745d26d..972b78b936 100644 --- a/examples/uuid/README.md +++ b/examples/uuid/README.md @@ -11,9 +11,26 @@ GUID(Globals Unique Identifiers 全局统一标识符)是微软对UUID这个 世界上的任何两台计算机都不会生成重复的 GUID 值。GUID 主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。在 Windows 平台上,GUID 应用非常广泛:注册表、类及接口标识、数据库、甚至自动生成的机器名、目录名等。一个GUID可以在后台数据库中操作一个主键。 +## 适用于分布式唯一标识码的生成算法有哪些? + +- 利用数据库生成 +- 利用Redis/MongoDB/zookeeper生成 +- UUID + - UUID有基于MAC地址的,加上时间和时钟序列的,也有基于伪随机数的,基于加密哈希的。 +- Twitter的snowflake算法 + - Twitter开源,基于zk,41位时间戳(毫秒数)+10位机器的ID+12位毫秒内的流水号+1位符号位(永远是0)。 + - 优点:性能不错,单机内递增。 + - 缺点:依赖zk;依赖于机器时钟,分布式环境内可能会不是全局递增。 +- 百度 UidGenerator + - UidGenerator是百度开源的分布式ID生成器,基于于snowflake算法的实现,看起来感觉还行。不过,国内开源的项目维护性真是担忧。 +- 美团 Leaf + - Leaf 是美团开源的分布式ID生成器,能保证全局唯一性、趋势递增、单调递增、信息安全,里面也提到了几种分布式方案的对比,但也需要依赖关系数据库、Zookeeper等中间件。 + 参考资料: - https://blog.csdn.net/forlong401/article/details/7580147 - https://blog.csdn.net/yuanlianming663/article/details/1842267 - https://www.cnblogs.com/pangguoming/p/7090906.html - http://www.cnblogs.com/snandy/p/3261754.html +- https://m.zjurl.cn/answer/6640244087003808014/?iid=59688834959 +- https://tech.meituan.com/2017/04/21/mt-leaf.html diff --git a/src/data-structures/hash-table/README.zh-CN.md b/src/data-structures/hash-table/README.zh-CN.md index a26640f041..eecfeb91a4 100644 --- a/src/data-structures/hash-table/README.zh-CN.md +++ b/src/data-structures/hash-table/README.zh-CN.md @@ -56,3 +56,4 @@ end Hash - [Wikipedia](https://en.wikipedia.org/wiki/Hash_table) - [YouTube](https://www.youtube.com/watch?v=shs0KM3wKv8&index=4&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8) +- [LinkedHashMap、HashMap比较](https://www.jianshu.com/p/979bc680b79f) diff --git a/src/data-structures/linked-list/LinkedList.js b/src/data-structures/linked-list/LinkedList.js index 4ef73fa802..ba7d0e3ee1 100644 --- a/src/data-structures/linked-list/LinkedList.js +++ b/src/data-structures/linked-list/LinkedList.js @@ -234,16 +234,6 @@ export default class LinkedList { return nodes; } - /** - * @param {*[]} values - Array of values that need to be converted to linked list. - * @return {LinkedList} - */ - fromArray(values) { - values.forEach(value => this.append(value)); - - return this; - } - /** * @param {function} [callback] * @return {string} diff --git a/src/data-structures/linked-list/README.zh-CN.md b/src/data-structures/linked-list/README.zh-CN.md index 4d3ac595f2..6aa0f293f7 100644 --- a/src/data-structures/linked-list/README.zh-CN.md +++ b/src/data-structures/linked-list/README.zh-CN.md @@ -163,6 +163,12 @@ end ReverseTraversal | :-------: | :-------: | :-------: | :-------: | | O(n) | O(n) | O(1) | O(1) | +这里删除的时间复杂度怎么会是 O(1) 呢,这里明明需要遍历,应该是O(n) + +如果已知需要删除的**节点**,那么可以使用以下方法优化到 O(1) + +参考:https://mp.weixin.qq.com/s/4Tg_NsXS8Z4DQPBIxwJplg + ### 空间复杂度 O(n) diff --git a/src/data-types/index.js b/src/data-types/index.js index cd935b08ec..63017a084c 100644 --- a/src/data-types/index.js +++ b/src/data-types/index.js @@ -1,4 +1,3 @@ - /* eslint no-var: 0, no-unused-vars: 0, prefer-const: 0 */ // number var nine = 9; diff --git a/ts/data-types/index.ts b/ts/data-types/index.ts new file mode 100644 index 0000000000..d4febf6df1 --- /dev/null +++ b/ts/data-types/index.ts @@ -0,0 +1,30 @@ + +/* eslint no-var: 0, no-unused-vars: 0, prefer-const: 0 */ + +// number +var nine = 9; + +const three: number = 3; +let two: number = 2; + +// boolean +const bool: boolean = false; + +// 命名名称必须有效,改为如下 +const decThree: number = 3; +let decTwo: number = 2; +let testa: number = 2; + +// boolean +let isDone: boolean = false; + +// string +const city: string = 'shanghai'; + +// null +let nul: null = null; + +// undefined +let empty; + +// let bigInter = 23142314231412345663451234n; From 6a07d0a6dfe311481eb68040197223653daa57be Mon Sep 17 00:00:00 2001 From: cloudyan <1395093509@qq.com> Date: Wed, 5 Jun 2024 20:17:35 +0800 Subject: [PATCH 8/8] feat: update rc --- .npmrc | 1 + .nvmrc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.npmrc b/.npmrc index b6f27f1359..1d456dd784 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ engine-strict=true +registry=https://registry.npmjs.org/ diff --git a/.nvmrc b/.nvmrc index 7fd023741b..9bcccb9439 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v16.15.0 +v20.13.1