From 05f005400583f2febae838cdbe5ffe0eb42f9ab5 Mon Sep 17 00:00:00 2001 From: krahets Date: Wed, 8 Feb 2023 19:45:06 +0800 Subject: [PATCH] Add build script for JS and TS codes. --- .../leetcode_two_sum.cpp | 56 ++--- .../leetcode_two_sum.cs | 24 +- .../leetcode_two_sum.java | 21 +- .../chapter_array_and_linkedlist/array.js | 2 +- .../linkedlist_stack.js | 2 +- .../leetcode_two_sum.py | 38 ++- .../chapter_searching/binary_search.ts | 4 +- docs/chapter_array_and_linkedlist/array.md | 126 ++-------- .../linked_list.md | 47 +--- docs/chapter_array_and_linkedlist/list.md | 181 +------------- .../space_complexity.md | 144 +---------- .../space_time_tradeoff.md | 67 +---- .../time_complexity.md | 230 ++---------------- docs/chapter_hashing/hash_map.md | 95 +------- docs/chapter_heap/heap.md | 208 ++-------------- docs/chapter_searching/binary_search.md | 72 +----- docs/chapter_searching/hashing_search.md | 28 +-- docs/chapter_searching/linear_search.md | 55 +---- docs/chapter_sorting/bubble_sort.md | 70 +----- docs/chapter_sorting/insertion_sort.md | 29 +-- docs/chapter_sorting/quick_sort.md | 106 +------- docs/chapter_stack_and_queue/queue.md | 211 +--------------- docs/chapter_stack_and_queue/stack.md | 180 +------------- docs/chapter_tree/avl_tree.md | 132 +--------- docs/chapter_tree/binary_search_tree.md | 194 +-------------- docs/chapter_tree/binary_tree_traversal.md | 104 +------- docs/utils/deploy.sh | 14 +- docs/utils/extract_code_jsts.py | 4 +- 28 files changed, 227 insertions(+), 2217 deletions(-) diff --git a/codes/cpp/chapter_computational_complexity/leetcode_two_sum.cpp b/codes/cpp/chapter_computational_complexity/leetcode_two_sum.cpp index 2f99bc007..f50a3f700 100644 --- a/codes/cpp/chapter_computational_complexity/leetcode_two_sum.cpp +++ b/codes/cpp/chapter_computational_complexity/leetcode_two_sum.cpp @@ -7,38 +7,32 @@ #include "../include/include.hpp" /* 方法一:暴力枚举 */ -class SolutionBruteForce { -public: - vector twoSum(vector& nums, int target) { - int size = nums.size(); - // 两层循环,时间复杂度 O(n^2) - for (int i = 0; i < size - 1; i++) { - for (int j = i + 1; j < size; j++) { - if (nums[i] + nums[j] == target) - return { i, j }; - } +vector twoSumBruteForce(vector& nums, int target) { + int size = nums.size(); + // 两层循环,时间复杂度 O(n^2) + for (int i = 0; i < size - 1; i++) { + for (int j = i + 1; j < size; j++) { + if (nums[i] + nums[j] == target) + return { i, j }; } - return {}; } -}; + return {}; +} /* 方法二:辅助哈希表 */ -class SolutionHashMap { -public: - vector twoSum(vector& nums, int target) { - int size = nums.size(); - // 辅助哈希表,空间复杂度 O(n) - unordered_map dic; - // 单层循环,时间复杂度 O(n) - for (int i = 0; i < size; i++) { - if (dic.find(target - nums[i]) != dic.end()) { - return { dic[target - nums[i]], i }; - } - dic.emplace(nums[i], i); +vector twoSumHashTable(vector& nums, int target) { + int size = nums.size(); + // 辅助哈希表,空间复杂度 O(n) + unordered_map dic; + // 单层循环,时间复杂度 O(n) + for (int i = 0; i < size; i++) { + if (dic.find(target - nums[i]) != dic.end()) { + return { dic[target - nums[i]], i }; } - return {}; + dic.emplace(nums[i], i); } -}; + return {}; +} int main() { @@ -48,19 +42,13 @@ int main() { // ====== Driver Code ====== // 方法一 - SolutionBruteForce* slt1 = new SolutionBruteForce(); - vector res = slt1->twoSum(nums, target); + vector res = twoSumBruteForce(nums, target); cout << "方法一 res = "; PrintUtil::printVector(res); // 方法二 - SolutionHashMap* slt2 = new SolutionHashMap(); - res = slt2->twoSum(nums, target); + res = twoSumHashTable(nums, target); cout << "方法二 res = "; PrintUtil::printVector(res); - // 释放内存 - delete slt1; - delete slt2; - return 0; } diff --git a/codes/csharp/chapter_computational_complexity/leetcode_two_sum.cs b/codes/csharp/chapter_computational_complexity/leetcode_two_sum.cs index c5182138c..37fe60c04 100644 --- a/codes/csharp/chapter_computational_complexity/leetcode_two_sum.cs +++ b/codes/csharp/chapter_computational_complexity/leetcode_two_sum.cs @@ -8,10 +8,10 @@ using NUnit.Framework; namespace hello_algo.chapter_computational_complexity { - /* 方法一:暴力枚举 */ - class SolutionBruteForce + public class leetcode_two_sum { - public int[] twoSum(int[] nums, int target) + /* 方法一:暴力枚举 */ + public static int[] twoSumBruteForce(int[] nums, int target) { int size = nums.Length; // 两层循环,时间复杂度 O(n^2) @@ -25,12 +25,9 @@ namespace hello_algo.chapter_computational_complexity } return new int[0]; } - } - /* 方法二:辅助哈希表 */ - class SolutionHashMap - { - public int[] twoSum(int[] nums, int target) + /* 方法二:辅助哈希表 */ + public static int[] twoSumHashTable(int[] nums, int target) { int size = nums.Length; // 辅助哈希表,空间复杂度 O(n) @@ -46,10 +43,7 @@ namespace hello_algo.chapter_computational_complexity } return new int[0]; } - } - public class leetcode_two_sum - { [Test] public void Test() { @@ -59,13 +53,11 @@ namespace hello_algo.chapter_computational_complexity // ====== Driver Code ====== // 方法一 - SolutionBruteForce slt1 = new SolutionBruteForce(); - int[] res = slt1.twoSum(nums, target); + int[] res = twoSumBruteForce(nums, target); Console.WriteLine("方法一 res = " + string.Join(",", res)); // 方法二 - SolutionHashMap slt2 = new SolutionHashMap(); - res = slt2.twoSum(nums, target); + res = twoSumHashTable(nums, target); Console.WriteLine("方法二 res = " + string.Join(",", res)); } } -} +} \ No newline at end of file diff --git a/codes/java/chapter_computational_complexity/leetcode_two_sum.java b/codes/java/chapter_computational_complexity/leetcode_two_sum.java index 3e3fe8a8f..bf76868a1 100644 --- a/codes/java/chapter_computational_complexity/leetcode_two_sum.java +++ b/codes/java/chapter_computational_complexity/leetcode_two_sum.java @@ -8,9 +8,10 @@ package chapter_computational_complexity; import java.util.*; -/* 方法一:暴力枚举 */ -class SolutionBruteForce { - public int[] twoSum(int[] nums, int target) { + +public class leetcode_two_sum { + /* 方法一:暴力枚举 */ + static int[] twoSumBruteForce(int[] nums, int target) { int size = nums.length; // 两层循环,时间复杂度 O(n^2) for (int i = 0; i < size - 1; i++) { @@ -21,11 +22,9 @@ class SolutionBruteForce { } return new int[0]; } -} -/* 方法二:辅助哈希表 */ -class SolutionHashMap { - public int[] twoSum(int[] nums, int target) { + /* 方法二:辅助哈希表 */ + static int[] twoSumHashTable(int[] nums, int target) { int size = nums.length; // 辅助哈希表,空间复杂度 O(n) Map dic = new HashMap<>(); @@ -38,9 +37,7 @@ class SolutionHashMap { } return new int[0]; } -} -public class leetcode_two_sum { public static void main(String[] args) { // ======= Test Case ======= int[] nums = { 2,7,11,15 }; @@ -48,12 +45,10 @@ public class leetcode_two_sum { // ====== Driver Code ====== // 方法一 - SolutionBruteForce slt1 = new SolutionBruteForce(); - int[] res = slt1.twoSum(nums, target); + int[] res = twoSumBruteForce(nums, target); System.out.println("方法一 res = " + Arrays.toString(res)); // 方法二 - SolutionHashMap slt2 = new SolutionHashMap(); - res = slt2.twoSum(nums, target); + res = twoSumHashTable(nums, target); System.out.println("方法二 res = " + Arrays.toString(res)); } } diff --git a/codes/javascript/chapter_array_and_linkedlist/array.js b/codes/javascript/chapter_array_and_linkedlist/array.js index 191b6f3fa..816f35ebe 100644 --- a/codes/javascript/chapter_array_and_linkedlist/array.js +++ b/codes/javascript/chapter_array_and_linkedlist/array.js @@ -4,7 +4,7 @@ * Author: IsChristina (christinaxia77@foxmail.com) */ -/* 随机访问元素 */ +/* 随机返回一个数组元素 */ function randomAccess(nums) { // 在区间 [0, nums.length) 中随机抽取一个数字 const random_index = Math.floor(Math.random() * nums.length); diff --git a/codes/javascript/chapter_stack_and_queue/linkedlist_stack.js b/codes/javascript/chapter_stack_and_queue/linkedlist_stack.js index 6ad3b96e4..ba6316049 100644 --- a/codes/javascript/chapter_stack_and_queue/linkedlist_stack.js +++ b/codes/javascript/chapter_stack_and_queue/linkedlist_stack.js @@ -44,7 +44,7 @@ class LinkedListStack { /* 访问栈顶元素 */ peek() { if (!this.#stackPeek) - throw new Error("栈为空!"); + throw new Error("栈为空"); return this.#stackPeek.val; } diff --git a/codes/python/chapter_computational_complexity/leetcode_two_sum.py b/codes/python/chapter_computational_complexity/leetcode_two_sum.py index 06ca397c3..9b71942ab 100644 --- a/codes/python/chapter_computational_complexity/leetcode_two_sum.py +++ b/codes/python/chapter_computational_complexity/leetcode_two_sum.py @@ -9,26 +9,24 @@ sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) from include import * """ 方法一:暴力枚举 """ -class SolutionBruteForce: - def twoSum(self, nums: List[int], target: int) -> List[int]: - # 两层循环,时间复杂度 O(n^2) - for i in range(len(nums) - 1): - for j in range(i + 1, len(nums)): - if nums[i] + nums[j] == target: - return i, j - return [] +def two_sum_brute_force(nums: List[int], target: int) -> List[int]: + # 两层循环,时间复杂度 O(n^2) + for i in range(len(nums) - 1): + for j in range(i + 1, len(nums)): + if nums[i] + nums[j] == target: + return i, j + return [] """ 方法二:辅助哈希表 """ -class SolutionHashMap: - def twoSum(self, nums: List[int], target: int) -> List[int]: - # 辅助哈希表,空间复杂度 O(n) - dic = {} - # 单层循环,时间复杂度 O(n) - for i in range(len(nums)): - if target - nums[i] in dic: - return dic[target - nums[i]], i - dic[nums[i]] = i - return [] +def two_sum_hash_table(nums: List[int], target: int) -> List[int]: + # 辅助哈希表,空间复杂度 O(n) + dic = {} + # 单层循环,时间复杂度 O(n) + for i in range(len(nums)): + if target - nums[i] in dic: + return dic[target - nums[i]], i + dic[nums[i]] = i + return [] """ Driver Code """ @@ -39,8 +37,8 @@ if __name__ == '__main__': # ====== Driver Code ====== # 方法一 - res = SolutionBruteForce().twoSum(nums, target) + res = two_sum_brute_force(nums, target) print("方法一 res =", res) # 方法二 - res = SolutionHashMap().twoSum(nums, target) + res = two_sum_hash_table(nums, target) print("方法二 res =", res) diff --git a/codes/typescript/chapter_searching/binary_search.ts b/codes/typescript/chapter_searching/binary_search.ts index d06d164a8..d0c416833 100644 --- a/codes/typescript/chapter_searching/binary_search.ts +++ b/codes/typescript/chapter_searching/binary_search.ts @@ -5,7 +5,7 @@ */ /* 二分查找(双闭区间) */ -const binarySearch = function (nums: number[], target: number): number { +function binarySearch(nums: number[], target: number): number { // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 let i = 0, j = nums.length - 1; // 循环,当搜索区间为空时跳出(当 i > j 时为空) @@ -23,7 +23,7 @@ const binarySearch = function (nums: number[], target: number): number { } /* 二分查找(左闭右开) */ -const binarySearch1 = function (nums: number[], target: number): number { +function binarySearch1(nums: number[], target: number): number { // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 let i = 0, j = nums.length; // 循环,当搜索区间为空时跳出(当 i = j 时为空) diff --git a/docs/chapter_array_and_linkedlist/array.md b/docs/chapter_array_and_linkedlist/array.md index 778e97801..e6cf9b649 100755 --- a/docs/chapter_array_and_linkedlist/array.md +++ b/docs/chapter_array_and_linkedlist/array.md @@ -148,27 +148,13 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "JavaScript" ```javascript title="array.js" - /* 随机返回一个数组元素 */ - function randomAccess(nums) { - // 在区间 [0, nums.length) 中随机抽取一个数字 - const random_index = Math.floor(Math.random() * nums.length); - // 获取并返回随机元素 - const random_num = nums[random_index]; - return random_num; - } + [class]{}-[func]{randomAccess} ``` === "TypeScript" ```typescript title="array.ts" - /* 随机返回一个数组元素 */ - function randomAccess(nums: number[]): number { - // 在区间 [0, nums.length) 中随机抽取一个数字 - const random_index = Math.floor(Math.random() * nums.length); - // 获取并返回随机元素 - const random_num = nums[random_index]; - return random_num; - } + [class]{}-[func]{randomAccess} ``` === "C" @@ -259,33 +245,13 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "JavaScript" ```javascript title="array.js" - /* 扩展数组长度 */ - function extend(nums, enlarge) { - // 初始化一个扩展长度后的数组 - const res = new Array(nums.length + enlarge).fill(0); - // 将原数组中的所有元素复制到新数组 - for (let i = 0; i < nums.length; i++) { - res[i] = nums[i]; - } - // 返回扩展后的新数组 - return res; - } + [class]{}-[func]{extend} ``` === "TypeScript" ```typescript title="array.ts" - /* 扩展数组长度 */ - function extend(nums: number[], enlarge: number): number[] { - // 初始化一个扩展长度后的数组 - const res = new Array(nums.length + enlarge).fill(0); - // 将原数组中的所有元素复制到新数组 - for (let i = 0; i < nums.length; i++) { - res[i] = nums[i]; - } - // 返回扩展后的新数组 - return res; - } + [class]{}-[func]{extend} ``` === "C" @@ -402,45 +368,17 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "JavaScript" ```javascript title="array.js" - /* 在数组的索引 index 处插入元素 num */ - function insert(nums, num, index) { - // 把索引 index 以及之后的所有元素向后移动一位 - for (let i = nums.length - 1; i > index; i--) { - nums[i] = nums[i - 1]; - } - // 将 num 赋给 index 处元素 - nums[index] = num; - } - - /* 删除索引 index 处元素 */ - function remove(nums, index) { - // 把索引 index 之后的所有元素向前移动一位 - for (let i = index; i < nums.length - 1; i++) { - nums[i] = nums[i + 1]; - } - } + [class]{}-[func]{insert} + + [class]{}-[func]{remove} ``` === "TypeScript" ```typescript title="array.ts" - /* 在数组的索引 index 处插入元素 num */ - function insert(nums: number[], num: number, index: number): void { - // 把索引 index 以及之后的所有元素向后移动一位 - for (let i = nums.length - 1; i > index; i--) { - nums[i] = nums[i - 1]; - } - // 将 num 赋给 index 处元素 - nums[index] = num; - } - - /* 删除索引 index 处元素 */ - function remove(nums: number[], index: number): void { - // 把索引 index 之后的所有元素向前移动一位 - for (let i = index; i < nums.length - 1; i++) { - nums[i] = nums[i + 1]; - } - } + [class]{}-[func]{insert} + + [class]{}-[func]{remove} ``` === "C" @@ -563,35 +501,13 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "JavaScript" ```javascript title="array.js" - /* 遍历数组 */ - function traverse(nums) { - let count = 0; - // 通过索引遍历数组 - for (let i = 0; i < nums.length; i++) { - count++; - } - // 直接遍历数组 - for (let num of nums) { - count += 1; - } - } + [class]{}-[func]{traverse} ``` === "TypeScript" ```typescript title="array.ts" - /* 遍历数组 */ - function traverse(nums: number[]): void { - let count = 0; - // 通过索引遍历数组 - for (let i = 0; i < nums.length; i++) { - count++; - } - // 直接遍历数组 - for(let num of nums){ - count += 1; - } - } + [class]{}-[func]{traverse} ``` === "C" @@ -695,27 +611,13 @@ elementAddr = firtstElementAddr + elementLength * elementIndex === "JavaScript" ```javascript title="array.js" - /* 在数组中查找指定元素 */ - function find(nums, target) { - for (let i = 0; i < nums.length; i++) { - if (nums[i] == target) return i; - } - return -1; - } + [class]{}-[func]{find} ``` === "TypeScript" ```typescript title="array.ts" - /* 在数组中查找指定元素 */ - function find(nums: number[], target: number): number { - for (let i = 0; i < nums.length; i++) { - if (nums[i] === target) { - return i; - } - } - return -1; - } + [class]{}-[func]{find} ``` === "C" diff --git a/docs/chapter_array_and_linkedlist/linked_list.md b/docs/chapter_array_and_linkedlist/linked_list.md index 4ed87562c..1a94fe99c 100755 --- a/docs/chapter_array_and_linkedlist/linked_list.md +++ b/docs/chapter_array_and_linkedlist/linked_list.md @@ -538,30 +538,13 @@ comments: true === "JavaScript" ```javascript title="linked_list.js" - /* 访问链表中索引为 index 的结点 */ - function access(head, index) { - for (let i = 0; i < index; i++) { - if (!head) - return null; - head = head.next; - } - return head; - } + [class]{}-[func]{access} ``` === "TypeScript" ```typescript title="linked_list.ts" - /* 访问链表中索引为 index 的结点 */ - function access(head: ListNode | null, index: number): ListNode | null { - for (let i = 0; i < index; i++) { - if (!head) { - return null; - } - head = head.next; - } - return head; - } + [class]{}-[func]{access} ``` === "C" @@ -661,35 +644,13 @@ comments: true === "JavaScript" ```javascript title="linked_list.js" - /* 在链表中查找值为 target 的首个结点 */ - function find(head, target) { - let index = 0; - while (head !== null) { - if (head.val === target) { - return index; - } - head = head.next; - index += 1; - } - return -1; - } + [class]{}-[func]{find} ``` === "TypeScript" ```typescript title="linked_list.ts" - /* 在链表中查找值为 target 的首个结点 */ - function find(head: ListNode | null, target: number): number { - let index = 0; - while (head !== null) { - if (head.val === target) { - return index; - } - head = head.next; - index += 1; - } - return -1; - } + [class]{}-[func]{find} ``` === "C" diff --git a/docs/chapter_array_and_linkedlist/list.md b/docs/chapter_array_and_linkedlist/list.md index 4a84931d3..c90c5541b 100755 --- a/docs/chapter_array_and_linkedlist/list.md +++ b/docs/chapter_array_and_linkedlist/list.md @@ -836,190 +836,13 @@ comments: true === "JavaScript" ```javascript title="my_list.js" - /* 列表类简易实现 */ - class MyList { - #nums = new Array(); // 数组(存储列表元素) - #capacity = 10; // 列表容量 - #size = 0; // 列表长度(即当前元素数量) - #extendRatio = 2; // 每次列表扩容的倍数 - - /* 构造函数 */ - constructor() { - this.#nums = new Array(this.#capacity); - } - - /* 获取列表长度(即当前元素数量)*/ - size() { - return this.#size; - } - - /* 获取列表容量 */ - capacity() { - return this.#capacity; - } - - /* 访问元素 */ - get(index) { - // 索引如果越界则抛出异常,下同 - if (index < 0 || index >= this.#size) - throw new Error('索引越界'); - return this.#nums[index]; - } - - /* 更新元素 */ - set(index, num) { - if (index < 0 || index >= this.#size) - throw new Error('索引越界'); - this.#nums[index] = num; - } - - /* 尾部添加元素 */ - add(num) { - // 如果长度等于容量,则需要扩容 - if (this.#size === this.#capacity) { - this.extendCapacity(); - } - // 将新元素添加到列表尾部 - this.#nums[this.#size] = num; - this.#size++; - } - - /* 中间插入元素 */ - insert(index, num) { - if (index < 0 || index >= this.#size) - throw new Error('索引越界'); - // 元素数量超出容量时,触发扩容机制 - if (this.#size === this.#capacity) { - this.extendCapacity(); - } - // 将索引 index 以及之后的元素都向后移动一位 - for (let j = this.#size - 1; j >= index; j--) { - this.#nums[j + 1] = this.#nums[j]; - } - // 更新元素数量 - this.#nums[index] = num; - this.#size++; - } - - /* 删除元素 */ - remove(index) { - if (index < 0 || index >= this.#size) - throw new Error('索引越界'); - let num = this.#nums[index]; - // 将索引 index 之后的元素都向前移动一位 - for (let j = index; j < this.#size - 1; j++) { - this.#nums[j] = this.#nums[j + 1]; - } - // 更新元素数量 - this.#size--; - // 返回被删除元素 - return num; - } - - /* 列表扩容 */ - extendCapacity() { - // 新建一个长度为 size 的数组,并将原数组拷贝到新数组 - this.#nums = this.#nums.concat( - new Array(this.capacity() * (this.#extendRatio - 1)) - ); - // 更新列表容量 - this.#capacity = this.#nums.length; - } - } + [class]{MyList}-[func]{} ``` === "TypeScript" ```typescript title="my_list.ts" - /* 列表类简易实现 */ - class MyList { - private nums: Array; // 数组(存储列表元素) - private _capacity: number = 10; // 列表容量 - private _size: number = 0; // 列表长度(即当前元素数量) - private extendRatio: number = 2; // 每次列表扩容的倍数 - - /* 构造函数 */ - constructor() { - this.nums = new Array(this._capacity); - } - - /* 获取列表长度(即当前元素数量)*/ - public size(): number { - return this._size; - } - - /* 获取列表容量 */ - public capacity(): number { - return this._capacity; - } - - /* 访问元素 */ - public get(index: number): number { - // 索引如果越界则抛出异常,下同 - if (index < 0 || index >= this._size) - throw new Error('索引越界'); - return this.nums[index]; - } - - /* 更新元素 */ - public set(index: number, num: number): void { - if (index < 0 || index >= this._size) - throw new Error('索引越界'); - this.nums[index] = num; - } - - /* 尾部添加元素 */ - public add(num: number): void { - // 如果长度等于容量,则需要扩容 - if (this._size === this._capacity) - this.extendCapacity(); - // 将新元素添加到列表尾部 - this.nums[this._size] = num; - this._size++; - } - - /* 中间插入元素 */ - public insert(index: number, num: number): void { - if (index < 0 || index >= this._size) - throw new Error('索引越界'); - // 元素数量超出容量时,触发扩容机制 - if (this._size === this._capacity) { - this.extendCapacity(); - } - // 将索引 index 以及之后的元素都向后移动一位 - for (let j = this._size - 1; j >= index; j--) { - this.nums[j + 1] = this.nums[j]; - } - // 更新元素数量 - this.nums[index] = num; - this._size++; - } - - /* 删除元素 */ - public remove(index: number): number { - if (index < 0 || index >= this._size) - throw new Error('索引越界'); - let num = this.nums[index]; - // 将索引 index 之后的元素都向前移动一位 - for (let j = index; j < this._size - 1; j++) { - this.nums[j] = this.nums[j + 1]; - } - // 更新元素数量 - this._size--; - // 返回被删除元素 - return num; - } - - /* 列表扩容 */ - public extendCapacity(): void { - // 新建一个长度为 size 的数组,并将原数组拷贝到新数组 - this.nums = this.nums.concat( - new Array(this.capacity() * (this.extendRatio - 1)) - ); - // 更新列表容量 - this._capacity = this.nums.length; - } - } + [class]{MyList}-[func]{} ``` === "C" diff --git a/docs/chapter_computational_complexity/space_complexity.md b/docs/chapter_computational_complexity/space_complexity.md index e01be9b68..789009f1e 100755 --- a/docs/chapter_computational_complexity/space_complexity.md +++ b/docs/chapter_computational_complexity/space_complexity.md @@ -623,43 +623,13 @@ $$ === "JavaScript" ```javascript title="space_complexity.js" - /* 常数阶 */ - function constant(n) { - // 常量、变量、对象占用 O(1) 空间 - const a = 0; - const b = 0; - const nums = new Array(10000); - const node = new ListNode(0); - // 循环中的变量占用 O(1) 空间 - for (let i = 0; i < n; i++) { - const c = 0; - } - // 循环中的函数占用 O(1) 空间 - for (let i = 0; i < n; i++) { - constFunc(); - } - } + [class]{}-[func]{constant} ``` === "TypeScript" ```typescript title="space_complexity.ts" - /* 常数阶 */ - function constant(n: number): void { - // 常量、变量、对象占用 O(1) 空间 - const a = 0; - const b = 0; - const nums = new Array(10000); - const node = new ListNode(0); - // 循环中的变量占用 O(1) 空间 - for (let i = 0; i < n; i++) { - const c = 0; - } - // 循环中的函数占用 O(1) 空间 - for (let i = 0; i < n; i++) { - constFunc(); - } - } + [class]{}-[func]{constant} ``` === "C" @@ -786,41 +756,13 @@ $$ === "JavaScript" ```javascript title="space_complexity.js" - /* 线性阶 */ - function linear(n) { - // 长度为 n 的数组占用 O(n) 空间 - const nums = new Array(n); - // 长度为 n 的列表占用 O(n) 空间 - const nodes = []; - for (let i = 0; i < n; i++) { - nodes.push(new ListNode(i)); - } - // 长度为 n 的哈希表占用 O(n) 空间 - const map = new Map(); - for (let i = 0; i < n; i++) { - map.set(i, i.toString()); - } - } + [class]{}-[func]{linear} ``` === "TypeScript" ```typescript title="space_complexity.ts" - /* 线性阶 */ - function linear(n: number): void { - // 长度为 n 的数组占用 O(n) 空间 - const nums = new Array(n); - // 长度为 n 的列表占用 O(n) 空间 - const nodes: ListNode[] = []; - for (let i = 0; i < n; i++) { - nodes.push(new ListNode(i)); - } - // 长度为 n 的哈希表占用 O(n) 空间 - const map = new Map(); - for (let i = 0; i < n; i++) { - map.set(i, i.toString()); - } - } + [class]{}-[func]{linear} ``` === "C" @@ -929,23 +871,13 @@ $$ === "JavaScript" ```javascript title="space_complexity.js" - /* 线性阶(递归实现) */ - function linearRecur(n) { - console.log(`递归 n = ${n}`); - if (n === 1) return; - linearRecur(n - 1); - } + [class]{}-[func]{linearRecur} ``` === "TypeScript" ```typescript title="space_complexity.ts" - /* 线性阶(递归实现) */ - function linearRecur(n: number): void { - console.log(`递归 n = ${n}`); - if (n === 1) return; - linearRecur(n - 1); - } + [class]{}-[func]{linearRecur} ``` === "C" @@ -1032,39 +964,13 @@ $$ === "JavaScript" ```javascript title="space_complexity.js" - /* 平方阶 */ - function quadratic(n) { - // 矩阵占用 O(n^2) 空间 - const numMatrix = Array(n).fill(null).map(() => Array(n).fill(null)); - // 二维列表占用 O(n^2) 空间 - const numList = []; - for (let i = 0; i < n; i++) { - const tmp = []; - for (let j = 0; j < n; j++) { - tmp.push(0); - } - numList.push(tmp); - } - } + [class]{}-[func]{quadratic} ``` === "TypeScript" ```typescript title="space_complexity.ts" - /* 平方阶 */ - function quadratic(n: number): void { - // 矩阵占用 O(n^2) 空间 - const numMatrix = Array(n).fill(null).map(() => Array(n).fill(null)); - // 二维列表占用 O(n^2) 空间 - const numList = []; - for (let i = 0; i < n; i++) { - const tmp = []; - for (let j = 0; j < n; j++) { - tmp.push(0); - } - numList.push(tmp); - } - } + [class]{}-[func]{quadratic} ``` === "C" @@ -1163,25 +1069,13 @@ $$ === "JavaScript" ```javascript title="space_complexity.js" - /* 平方阶(递归实现) */ - function quadraticRecur(n) { - if (n <= 0) return 0; - const nums = new Array(n); - console.log(`递归 n = ${n} 中的 nums 长度 = ${nums.length}`); - return quadraticRecur(n - 1); - } + [class]{}-[func]{quadraticRecur} ``` === "TypeScript" ```typescript title="space_complexity.ts" - /* 平方阶(递归实现) */ - function quadraticRecur(n: number): number { - if (n <= 0) return 0; - const nums = new Array(n); - console.log(`递归 n = ${n} 中的 nums 长度 = ${nums.length}`); - return quadraticRecur(n - 1); - } + [class]{}-[func]{quadraticRecur} ``` === "C" @@ -1273,27 +1167,13 @@ $$ === "JavaScript" ```javascript title="space_complexity.js" - /* 指数阶(建立满二叉树) */ - function buildTree(n) { - if (n === 0) return null; - const root = new TreeNode(0); - root.left = buildTree(n - 1); - root.right = buildTree(n - 1); - return root; - } + [class]{}-[func]{buildTree} ``` === "TypeScript" ```typescript title="space_complexity.ts" - /* 指数阶(建立满二叉树) */ - function buildTree(n: number): TreeNode | null { - if (n === 0) return null; - const root = new TreeNode(0); - root.left = buildTree(n - 1); - root.right = buildTree(n - 1); - return root; - } + [class]{}-[func]{buildTree} ``` === "C" diff --git a/docs/chapter_computational_complexity/space_time_tradeoff.md b/docs/chapter_computational_complexity/space_time_tradeoff.md index da4503310..048bc3316 100755 --- a/docs/chapter_computational_complexity/space_time_tradeoff.md +++ b/docs/chapter_computational_complexity/space_time_tradeoff.md @@ -33,19 +33,19 @@ comments: true === "Java" ```java title="leetcode_two_sum.java" - [class]{SolutionBruteForce}-[func]{} + [class]{leetcode_two_sum}-[func]{twoSumBruteForce} ``` === "C++" ```cpp title="leetcode_two_sum.cpp" - [class]{SolutionBruteForce}-[func]{} + [class]{}-[func]{twoSumBruteForce} ``` === "Python" ```python title="leetcode_two_sum.py" - [class]{SolutionBruteForce}-[func]{} + [class]{}-[func]{two_sum_brute_force} ``` === "Go" @@ -68,35 +68,13 @@ comments: true === "JavaScript" ```javascript title="leetcode_two_sum.js" - function twoSumBruteForce(nums, target) { - const n = nums.length; - // 两层循环,时间复杂度 O(n^2) - for (let i = 0; i < n; i++) { - for (let j = i + 1; j < n; j++) { - if (nums[i] + nums[j] === target) { - return [i, j]; - } - } - } - return []; - } + [class]{}-[func]{twoSumBruteForce} ``` === "TypeScript" ```typescript title="leetcode_two_sum.ts" - function twoSumBruteForce(nums: number[], target: number): number[] { - const n = nums.length; - // 两层循环,时间复杂度 O(n^2) - for (let i = 0; i < n; i++) { - for (let j = i + 1; j < n; j++) { - if (nums[i] + nums[j] === target) { - return [i, j]; - } - } - } - return []; - }; + [class]{}-[func]{twoSumBruteForce} ``` === "C" @@ -174,19 +152,19 @@ comments: true === "Java" ```java title="leetcode_two_sum.java" - [class]{SolutionHashMap}-[func]{} + [class]{leetcode_two_sum}-[func]{twoSumHashTable} ``` === "C++" ```cpp title="leetcode_two_sum.cpp" - [class]{SolutionHashMap}-[func]{} + [class]{}-[func]{twoSumHashTable} ``` === "Python" ```python title="leetcode_two_sum.py" - [class]{SolutionHashMap}-[func]{} + [class]{}-[func]{two_sum_hash_table} ``` === "Go" @@ -209,38 +187,13 @@ comments: true === "JavaScript" ```javascript title="leetcode_two_sum.js" - function twoSumHashTable(nums, target) { - // 辅助哈希表,空间复杂度 O(n) - let m = {}; - // 单层循环,时间复杂度 O(n) - for (let i = 0; i < nums.length; i++) { - if (m[nums[i]] !== undefined) { - return [m[nums[i]], i]; - } else { - m[target - nums[i]] = i; - } - } - return []; - } + [class]{}-[func]{twoSumHashTable} ``` === "TypeScript" ```typescript title="leetcode_two_sum.ts" - function twoSumHashTable(nums: number[], target: number): number[] { - // 辅助哈希表,空间复杂度 O(n) - let m: Map = new Map(); - // 单层循环,时间复杂度 O(n) - for (let i = 0; i < nums.length; i++) { - let index = m.get(nums[i]); - if (index !== undefined) { - return [index, i]; - } else { - m.set(target - nums[i], i); - } - } - return []; - }; + [class]{}-[func]{twoSumHashTable} ``` === "C" diff --git a/docs/chapter_computational_complexity/time_complexity.md b/docs/chapter_computational_complexity/time_complexity.md index 770ad3031..61f0ecd61 100755 --- a/docs/chapter_computational_complexity/time_complexity.md +++ b/docs/chapter_computational_complexity/time_complexity.md @@ -827,25 +827,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 常数阶 */ - function constant(n) { - let count = 0; - const size = 100000; - for (let i = 0; i < size; i++) count++; - return count; - } + [class]{}-[func]{constant} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 常数阶 */ - function constant(n: number): number { - let count = 0; - const size = 100000; - for (let i = 0; i < size; i++) count++; - return count; - } + [class]{}-[func]{constant} ``` === "C" @@ -945,23 +933,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 线性阶 */ - function linear(n) { - let count = 0; - for (let i = 0; i < n; i++) count++; - return count; - } + [class]{}-[func]{linear} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 线性阶 */ - function linear(n: number): number { - let count = 0; - for (let i = 0; i < n; i++) count++; - return count; - } + [class]{}-[func]{linear} ``` === "C" @@ -1058,29 +1036,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 线性阶(遍历数组) */ - function arrayTraversal(nums) { - let count = 0; - // 循环次数与数组长度成正比 - for (let i = 0; i < nums.length; i++) { - count++; - } - return count; - } + [class]{}-[func]{arrayTraversal} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 线性阶(遍历数组) */ - function arrayTraversal(nums: number[]): number { - let count = 0; - // 循环次数与数组长度成正比 - for (let i = 0; i < nums.length; i++) { - count++; - } - return count; - } + [class]{}-[func]{arrayTraversal} ``` === "C" @@ -1182,33 +1144,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 平方阶 */ - function quadratic(n) { - let count = 0; - // 循环次数与数组长度成平方关系 - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - count++; - } - } - return count; - } + [class]{}-[func]{quadratic} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 平方阶 */ - function quadratic(n: number): number { - let count = 0; - // 循环次数与数组长度成平方关系 - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - count++; - } - } - return count; - } + [class]{}-[func]{quadratic} ``` === "C" @@ -1334,47 +1276,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 平方阶(冒泡排序) */ - function bubbleSort(nums) { - let count = 0; // 计数器 - // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (let i = nums.length - 1; i > 0; i--) { - // 内循环:冒泡操作 - for (let j = 0; j < i; j++) { - if (nums[j] > nums[j + 1]) { - // 交换 nums[j] 与 nums[j + 1] - let tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; - count += 3; // 元素交换包含 3 个单元操作 - } - } - } - return count; - } + [class]{}-[func]{bubbleSort} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 平方阶(冒泡排序) */ - function bubbleSort(nums: number[]): number { - let count = 0; // 计数器 - // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (let i = nums.length - 1; i > 0; i--) { - // 内循环:冒泡操作 - for (let j = 0; j < i; j++) { - if (nums[j] > nums[j + 1]) { - // 交换 nums[j] 与 nums[j + 1] - let tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; - count += 3; // 元素交换包含 3 个单元操作 - } - } - } - return count; - } + [class]{}-[func]{bubbleSort} ``` === "C" @@ -1525,40 +1433,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 指数阶(循环实现) */ - function exponential(n) { - let count = 0, - base = 1; - // cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1) - for (let i = 0; i < n; i++) { - for (let j = 0; j < base; j++) { - count++; - } - base *= 2; - } - // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1 - return count; - } - + [class]{}-[func]{exponential} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 指数阶(循环实现) */ - function exponential(n: number): number { - let count = 0, - base = 1; - // cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1) - for (let i = 0; i < n; i++) { - for (let j = 0; j < base; j++) { - count++; - } - base *= 2; - } - // count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1 - return count; - } + [class]{}-[func]{exponential} ``` === "C" @@ -1680,22 +1561,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 指数阶(递归实现) */ - function expRecur(n) { - if (n == 1) return 1; - return expRecur(n - 1) + expRecur(n - 1) + 1; - } + [class]{}-[func]{expRecur} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 指数阶(递归实现) */ - function expRecur(n: number): number { - if (n == 1) return 1; - return expRecur(n - 1) + expRecur(n - 1) + 1; - } - + [class]{}-[func]{expRecur} ``` === "C" @@ -1784,29 +1656,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 对数阶(循环实现) */ - function logarithmic(n) { - let count = 0; - while (n > 1) { - n = n / 2; - count++; - } - return count; - } + [class]{}-[func]{logarithmic} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 对数阶(循环实现) */ - function logarithmic(n: number): number { - let count = 0; - while (n > 1) { - n = n / 2; - count++; - } - return count; - } + [class]{}-[func]{logarithmic} ``` === "C" @@ -1910,21 +1766,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 对数阶(递归实现) */ - function logRecur(n) { - if (n <= 1) return 0; - return logRecur(n / 2) + 1; - } + [class]{}-[func]{logRecur} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 对数阶(递归实现) */ - function logRecur(n: number): number { - if (n <= 1) return 0; - return logRecur(n / 2) + 1; - } + [class]{}-[func]{logRecur} ``` === "C" @@ -2015,29 +1863,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 线性对数阶 */ - function linearLogRecur(n) { - if (n <= 1) return 1; - let count = linearLogRecur(n / 2) + linearLogRecur(n / 2); - for (let i = 0; i < n; i++) { - count++; - } - return count; - } + [class]{}-[func]{linearLogRecur} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 线性对数阶 */ - function linearLogRecur(n: number): number { - if (n <= 1) return 1; - let count = linearLogRecur(n / 2) + linearLogRecur(n / 2); - for (let i = 0; i < n; i++) { - count++; - } - return count; - } + [class]{}-[func]{linearLogRecur} ``` === "C" @@ -2157,31 +1989,13 @@ $$ === "JavaScript" ```javascript title="time_complexity.js" - /* 阶乘阶(递归实现) */ - function factorialRecur(n) { - if (n == 0) return 1; - let count = 0; - // 从 1 个分裂出 n 个 - for (let i = 0; i < n; i++) { - count += factorialRecur(n - 1); - } - return count; - } + [class]{}-[func]{factorialRecur} ``` === "TypeScript" ```typescript title="time_complexity.ts" - /* 阶乘阶(递归实现) */ - function factorialRecur(n: number): number { - if (n == 0) return 1; - let count = 0; - // 从 1 个分裂出 n 个 - for (let i = 0; i < n; i++) { - count += factorialRecur(n - 1); - } - return count; - } + [class]{}-[func]{factorialRecur} ``` === "C" diff --git a/docs/chapter_hashing/hash_map.md b/docs/chapter_hashing/hash_map.md index 8359686f7..a03bb4932 100755 --- a/docs/chapter_hashing/hash_map.md +++ b/docs/chapter_hashing/hash_map.md @@ -491,100 +491,17 @@ $$ === "JavaScript" ```javascript title="array_hash_map.js" - /* 键值对 Number -> String */ - class Entry { - constructor(key, val) { - this.key = key; - this.val = val; - } - } - - /* 基于数组简易实现的哈希表 */ - class ArrayHashMap { - #bucket; - constructor() { - // 初始化一个长度为 100 的桶(数组) - this.#bucket = new Array(100).fill(null); - } - - /* 哈希函数 */ - #hashFunc(key) { - return key % 100; - } - - /* 查询操作 */ - get(key) { - let index = this.#hashFunc(key); - let entry = this.#bucket[index]; - if (entry === null) return null; - return entry.val; - } - - /* 添加操作 */ - set(key, val) { - let index = this.#hashFunc(key); - this.#bucket[index] = new Entry(key, val); - } - - /* 删除操作 */ - delete(key) { - let index = this.#hashFunc(key); - // 置为 null ,代表删除 - this.#bucket[index] = null; - } - } + [class]{Entry}-[func]{} + + [class]{ArrayHashMap}-[func]{} ``` === "TypeScript" ```typescript title="array_hash_map.ts" - /* 键值对 Number -> String */ - class Entry { - public key: number; - public val: string; - - constructor(key: number, val: string) { - this.key = key; - this.val = val; - } - } - - /* 基于数组简易实现的哈希表 */ - class ArrayHashMap { - - private readonly bucket: (Entry | null)[]; - - constructor() { - // 初始化一个长度为 100 的桶(数组) - this.bucket = (new Array(100)).fill(null); - } - - /* 哈希函数 */ - private hashFunc(key: number): number { - return key % 100; - } - - /* 查询操作 */ - public get(key: number): string | null { - let index = this.hashFunc(key); - let entry = this.bucket[index]; - if (entry === null) return null; - return entry.val; - } - - /* 添加操作 */ - public set(key: number, val: string) { - let index = this.hashFunc(key); - this.bucket[index] = new Entry(key, val); - } - - /* 删除操作 */ - public delete(key: number) { - let index = this.hashFunc(key); - // 置为 null ,代表删除 - this.bucket[index] = null; - } - } + [class]{Entry}-[func]{} + + [class]{ArrayHashMap}-[func]{} ``` === "C" diff --git a/docs/chapter_heap/heap.md b/docs/chapter_heap/heap.md index 6764b5cc7..420dca929 100644 --- a/docs/chapter_heap/heap.md +++ b/docs/chapter_heap/heap.md @@ -270,23 +270,11 @@ comments: true === "C++" ```cpp title="my_heap.cpp" - // 使用动态数组,这样无需考虑扩容问题 - vector maxHeap; + [class]{MaxHeap}-[func]{left} - /* 获取左子结点索引 */ - int left(int i) { - return 2 * i + 1; - } + [class]{MaxHeap}-[func]{right} - /* 获取右子结点索引 */ - int right(int i) { - return 2 * i + 2; - } - - /* 获取父结点索引 */ - int parent(int i) { - return (i - 1) / 2; // 向下取整 - } + [class]{MaxHeap}-[func]{parent} ``` === "Python" @@ -330,62 +318,21 @@ comments: true === "JavaScript" ```javascript title="my_heap.js" - #maxHeap; + [class]{MaxHeap}-[func]{#left} - /* 构造函数,建立空堆或根据输入列表建堆 */ - constructor(nums) { - // 将列表元素原封不动添加进堆 - this.#maxHeap = nums === undefined ? [] : [...nums]; - // 堆化除叶结点以外的其他所有结点 - for (let i = this.#parent(this.size() - 1); i >= 0; i--) { - this.#siftDown(i); - } - } + [class]{MaxHeap}-[func]{#right} - /* 获取左子结点索引 */ - #left(i) { - return 2 * i + 1; - } - - /* 获取右子结点索引 */ - #right(i) { - return 2 * i + 2; - } - - /* 获取父结点索引 */ - #parent(i) { - return Math.floor((i - 1) / 2); // 向下整除 - } + [class]{MaxHeap}-[func]{#parent} ``` === "TypeScript" ```typescript title="my_heap.ts" - private maxHeap: number[]; - /* 构造函数,建立空堆或根据输入列表建堆 */ - constructor(nums?: number[]) { - // 将列表元素原封不动添加进堆 - this.maxHeap = nums === undefined ? [] : [...nums]; - // 堆化除叶结点以外的其他所有结点 - for (let i = this.parent(this.size() - 1); i >= 0; i--) { - this.siftDown(i); - } - } + [class]{MaxHeap}-[func]{left} - /* 获取左子结点索引 */ - private left(i: number): number { - return 2 * i + 1; - } + [class]{MaxHeap}-[func]{right} - /* 获取右子结点索引 */ - private right(i: number): number { - return 2 * i + 2; - } - - /* 获取父结点索引 */ - private parent(i: number): number { - return Math.floor((i - 1) / 2); // 向下整除 - } + [class]{MaxHeap}-[func]{parent} ``` === "C" @@ -466,19 +413,13 @@ comments: true === "JavaScript" ```javascript title="my_heap.js" - /* 访问堆顶元素 */ - peek() { - return this.#maxHeap[0]; - } + [class]{MaxHeap}-[func]{peek} ``` === "TypeScript" ```typescript title="my_heap.ts" - /* 访问堆顶元素 */ - public peek(): number { - return this.maxHeap[0]; - } + [class]{MaxHeap}-[func]{peek} ``` === "C" @@ -587,53 +528,17 @@ comments: true === "JavaScript" ```javascript title="my_heap.js" - /* 元素入堆 */ - push(val) { - // 添加结点 - this.#maxHeap.push(val); - // 从底至顶堆化 - this.#siftUp(this.size() - 1); - } + [class]{MaxHeap}-[func]{push} - /* 从结点 i 开始,从底至顶堆化 */ - #siftUp(i) { - while (true) { - // 获取结点 i 的父结点 - const p = this.#parent(i); - // 当“越过根结点”或“结点无需修复”时,结束堆化 - if (p < 0 || this.#maxHeap[i] <= this.#maxHeap[p]) break; - // 交换两结点 - this.#swap(i, p); - // 循环向上堆化 - i = p; - } - } + [class]{MaxHeap}-[func]{#siftUp} ``` === "TypeScript" ```typescript title="my_heap.ts" - /* 元素入堆 */ - public push(val: number): void { - // 添加结点 - this.maxHeap.push(val); - // 从底至顶堆化 - this.siftUp(this.size() - 1); - } + [class]{MaxHeap}-[func]{push} - /* 从结点 i 开始,从底至顶堆化 */ - private siftUp(i: number): void { - while (true) { - // 获取结点 i 的父结点 - const p = this.parent(i); - // 当“越过根结点”或“结点无需修复”时,结束堆化 - if (p < 0 || this.maxHeap[i] <= this.maxHeap[p]) break; - // 交换两结点 - this.swap(i, p); - // 循环向上堆化 - i = p; - } - } + [class]{MaxHeap}-[func]{siftUp} ``` === "C" @@ -795,72 +700,17 @@ comments: true === "JavaScript" ```javascript title="my_heap.js" - /* 元素出堆 */ - poll() { - // 判空处理 - if (this.isEmpty()) throw new Error("堆为空"); - // 交换根结点与最右叶结点(即交换首元素与尾元素) - this.#swap(0, this.size() - 1); - // 删除结点 - const val = this.#maxHeap.pop(); - // 从顶至底堆化 - this.#siftDown(0); - // 返回堆顶元素 - return val; - } + [class]{MaxHeap}-[func]{poll} - /* 从结点 i 开始,从顶至底堆化 */ - #siftDown(i) { - while (true) { - // 判断结点 i, l, r 中值最大的结点,记为 ma - const l = this.#left(i), - r = this.#right(i); - let ma = i; - if (l < this.size() && this.#maxHeap[l] > this.#maxHeap[ma]) ma = l; - if (r < this.size() && this.#maxHeap[r] > this.#maxHeap[ma]) ma = r; - // 若结点 i 最大或索引 l, r 越界,则无需继续堆化,跳出 - if (ma == i) break; - // 交换两结点 - this.#swap(i, ma); - // 循环向下堆化 - i = ma; - } - } + [class]{MaxHeap}-[func]{#siftDown} ``` === "TypeScript" ```typescript title="my_heap.ts" - /* 元素出堆 */ - public poll(): number { - // 判空处理 - if (this.isEmpty()) throw new RangeError("Heap is empty."); - // 交换根结点与最右叶结点(即交换首元素与尾元素) - this.swap(0, this.size() - 1); - // 删除结点 - const val = this.maxHeap.pop(); - // 从顶至底堆化 - this.siftDown(0); - // 返回堆顶元素 - return val; - } + [class]{MaxHeap}-[func]{poll} - /* 从结点 i 开始,从顶至底堆化 */ - private siftDown(i: number): void { - while (true) { - // 判断结点 i, l, r 中值最大的结点,记为 ma - const l = this.left(i), r = this.right(i); - let ma = i; - if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l; - if (r < this.size() && this.maxHeap[r] > this.maxHeap[ma]) ma = r; - // 若结点 i 最大或索引 l, r 越界,则无需继续堆化,跳出 - if (ma == i) break; - // 交换两结点 - this.swap(i, ma); - // 循环向下堆化 - i = ma; - } - } + [class]{MaxHeap}-[func]{siftDown} ``` === "C" @@ -968,29 +818,13 @@ comments: true === "JavaScript" ```javascript title="my_heap.js" - /* 构造函数,建立空堆或根据输入列表建堆 */ - constructor(nums) { - // 将列表元素原封不动添加进堆 - this.#maxHeap = nums === undefined ? [] : [...nums]; - // 堆化除叶结点以外的其他所有结点 - for (let i = this.#parent(this.size() - 1); i >= 0; i--) { - this.#siftDown(i); - } - } + [class]{MaxHeap}-[func]{constructor} ``` === "TypeScript" ```typescript title="my_heap.ts" - /* 构造函数,建立空堆或根据输入列表建堆 */ - constructor(nums?: number[]) { - // 将列表元素原封不动添加进堆 - this.maxHeap = nums === undefined ? [] : [...nums]; - // 堆化除叶结点以外的其他所有结点 - for (let i = this.parent(this.size() - 1); i >= 0; i--) { - this.siftDown(i); - } - } + [class]{MaxHeap}-[func]{constructor} ``` === "C" diff --git a/docs/chapter_searching/binary_search.md b/docs/chapter_searching/binary_search.md index 0484baaa1..3d4064b25 100755 --- a/docs/chapter_searching/binary_search.md +++ b/docs/chapter_searching/binary_search.md @@ -95,45 +95,13 @@ $$ === "JavaScript" ```javascript title="binary_search.js" - /* 二分查找(双闭区间) */ - function binarySearch(nums, target) { - // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 - let i = 0, j = nums.length - 1; - // 循环,当搜索区间为空时跳出(当 i > j 时为空) - while (i <= j) { - let m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整 - if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中 - i = m + 1; - else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中 - j = m - 1; - else - return m; // 找到目标元素,返回其索引 - } - // 未找到目标元素,返回 -1 - return -1; - } + [class]{}-[func]{binarySearch} ``` === "TypeScript" ```typescript title="binary_search.ts" - /* 二分查找(双闭区间) */ - const binarySearch = function (nums: number[], target: number): number { - // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 - let i = 0, j = nums.length - 1; - // 循环,当搜索区间为空时跳出(当 i > j 时为空) - while (i <= j) { - const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m - if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中 - i = m + 1; - } else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m-1] 中 - j = m - 1; - } else { // 找到目标元素,返回其索引 - return m; - } - } - return -1; // 未找到目标元素,返回 -1 - } + [class]{}-[func]{binarySearch} ``` === "C" @@ -244,45 +212,13 @@ $$ === "JavaScript" ```javascript title="binary_search.js" - /* 二分查找(左闭右开) */ - function binarySearch1(nums, target) { - // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 - let i = 0, j = nums.length; - // 循环,当搜索区间为空时跳出(当 i = j 时为空) - while (i < j) { - let m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整 - if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中 - i = m + 1; - else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中 - j = m; - else // 找到目标元素,返回其索引 - return m; - } - // 未找到目标元素,返回 -1 - return -1; - } + [class]{}-[func]{binarySearch1} ``` === "TypeScript" ```typescript title="binary_search.ts" - /* 二分查找(左闭右开) */ - const binarySearch1 = function (nums: number[], target: number): number { - // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 - let i = 0, j = nums.length; - // 循环,当搜索区间为空时跳出(当 i = j 时为空) - while (i < j) { - const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m - if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j) 中 - i = m + 1; - } else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m) 中 - j = m; - } else { // 找到目标元素,返回其索引 - return m; - } - } - return -1; // 未找到目标元素,返回 -1 - } + [class]{}-[func]{binarySearch1} ``` === "C" diff --git a/docs/chapter_searching/hashing_search.md b/docs/chapter_searching/hashing_search.md index 1a544a2b5..85364eacc 100755 --- a/docs/chapter_searching/hashing_search.md +++ b/docs/chapter_searching/hashing_search.md @@ -52,23 +52,13 @@ comments: true === "JavaScript" ```javascript title="hashing_search.js" - /* 哈希查找(数组) */ - function hashingSearchArray(map, target) { - // 哈希表的 key: 目标元素,value: 索引 - // 若哈希表中无此 key ,返回 -1 - return map.has(target) ? map.get(target) : -1; - } + [class]{}-[func]{hashingSearchArray} ``` === "TypeScript" ```typescript title="hashing_search.ts" - /* 哈希查找(数组) */ - function hashingSearchArray(map: Map, target: number): number { - // 哈希表的 key: 目标元素,value: 索引 - // 若哈希表中无此 key ,返回 -1 - return map.has(target) ? map.get(target) as number : -1; - } + [class]{}-[func]{hashingSearchArray} ``` === "C" @@ -146,23 +136,13 @@ comments: true === "JavaScript" ```javascript title="hashing_search.js" - /* 哈希查找(链表) */ - function hashingSearchLinkedList(map, target) { - // 哈希表的 key: 目标结点值,value: 结点对象 - // 若哈希表中无此 key ,返回 null - return map.has(target) ? map.get(target) : null; - } + [class]{}-[func]{hashingSearchLinkedList} ``` === "TypeScript" ```typescript title="hashing_search.ts" - /* 哈希查找(链表) */ - function hashingSearchLinkedList(map: Map, target: number): ListNode | null { - // 哈希表的 key: 目标结点值,value: 结点对象 - // 若哈希表中无此 key ,返回 null - return map.has(target) ? map.get(target) as ListNode : null; - } + [class]{}-[func]{hashingSearchLinkedList} ``` === "C" diff --git a/docs/chapter_searching/linear_search.md b/docs/chapter_searching/linear_search.md index 60d58fe5e..f92b8af28 100755 --- a/docs/chapter_searching/linear_search.md +++ b/docs/chapter_searching/linear_search.md @@ -50,36 +50,13 @@ comments: true === "JavaScript" ```javascript title="linear_search.js" - /* 线性查找(数组) */ - function linearSearchArray(nums, target) { - // 遍历数组 - for (let i = 0; i < nums.length; i++) { - // 找到目标元素,返回其索引 - if (nums[i] === target) { - return i; - } - } - // 未找到目标元素,返回 -1 - return -1; - } - + [class]{}-[func]{linearSearchArray} ``` === "TypeScript" ```typescript title="linear_search.ts" - /* 线性查找(数组)*/ - function linearSearchArray(nums: number[], target: number): number { - // 遍历数组 - for (let i = 0; i < nums.length; i++) { - // 找到目标元素,返回其索引 - if (nums[i] === target) { - return i; - } - } - // 未找到目标元素,返回 -1 - return -1; - } + [class]{}-[func]{linearSearchArray} ``` === "C" @@ -171,37 +148,13 @@ comments: true === "JavaScript" ```javascript title="linear_search.js" - /* 线性查找(链表)*/ - function linearSearchLinkedList(head, target) { - // 遍历链表 - while(head) { - // 找到目标结点,返回之 - if(head.val === target) { - return head; - } - head = head.next; - } - // 未找到目标结点,返回 null - return null; - } + [class]{}-[func]{linearSearchLinkedList} ``` === "TypeScript" ```typescript title="linear_search.ts" - /* 线性查找(链表)*/ - function linearSearchLinkedList(head: ListNode | null, target: number): ListNode | null { - // 遍历链表 - while (head) { - // 找到目标结点,返回之 - if (head.val === target) { - return head; - } - head = head.next; - } - // 未找到目标结点,返回 null - return null; - } + [class]{}-[func]{linearSearchLinkedList} ``` === "C" diff --git a/docs/chapter_sorting/bubble_sort.md b/docs/chapter_sorting/bubble_sort.md index 9068b12eb..d10949350 100755 --- a/docs/chapter_sorting/bubble_sort.md +++ b/docs/chapter_sorting/bubble_sort.md @@ -86,41 +86,13 @@ comments: true === "JavaScript" ```javascript title="bubble_sort.js" - /* 冒泡排序 */ - function bubbleSort(nums) { - // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (let i = nums.length - 1; i > 0; i--) { - // 内循环:冒泡操作 - for (let j = 0; j < i; j++) { - if (nums[j] > nums[j + 1]) { - // 交换 nums[j] 与 nums[j + 1] - let tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; - } - } - } - } + [class]{}-[func]{bubbleSort} ``` === "TypeScript" ```typescript title="bubble_sort.ts" - /* 冒泡排序 */ - function bubbleSort(nums: number[]): void { - // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (let i = nums.length - 1; i > 0; i--) { - // 内循环:冒泡操作 - for (let j = 0; j < i; j++) { - if (nums[j] > nums[j + 1]) { - // 交换 nums[j] 与 nums[j + 1] - let tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; - } - } - } - } + [class]{}-[func]{bubbleSort} ``` === "C" @@ -257,47 +229,13 @@ comments: true === "JavaScript" ```javascript title="bubble_sort.js" - /* 冒泡排序(标志优化)*/ - function bubbleSortWithFlag(nums) { - // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (let i = nums.length - 1; i > 0; i--) { - let flag = false; // 初始化标志位 - // 内循环:冒泡操作 - for (let j = 0; j < i; j++) { - if (nums[j] > nums[j + 1]) { - // 交换 nums[j] 与 nums[j + 1] - let tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; - flag = true; // 记录交换元素 - } - } - if (!flag) break; // 此轮冒泡未交换任何元素,直接跳出 - } - } + [class]{}-[func]{bubbleSortWithFlag} ``` === "TypeScript" ```typescript title="bubble_sort.ts" - /* 冒泡排序(标志优化)*/ - function bubbleSortWithFlag(nums: number[]): void { - // 外循环:待排序元素数量为 n-1, n-2, ..., 1 - for (let i = nums.length - 1; i > 0; i--) { - let flag = false; // 初始化标志位 - // 内循环:冒泡操作 - for (let j = 0; j < i; j++) { - if (nums[j] > nums[j + 1]) { - // 交换 nums[j] 与 nums[j + 1] - let tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; - flag = true; // 记录交换元素 - } - } - if (!flag) break; // 此轮冒泡未交换任何元素,直接跳出 - } - } + [class]{}-[func]{bubbleSortWithFlag} ``` === "C" diff --git a/docs/chapter_sorting/insertion_sort.md b/docs/chapter_sorting/insertion_sort.md index 6f69a5a40..24fb718cc 100755 --- a/docs/chapter_sorting/insertion_sort.md +++ b/docs/chapter_sorting/insertion_sort.md @@ -64,38 +64,13 @@ comments: true === "JavaScript" ```javascript title="insertion_sort.js" - /* 插入排序 */ - function insertionSort(nums) { - // 外循环:base = nums[1], nums[2], ..., nums[n-1] - for (let i = 1; i < nums.length; i++) { - let base = nums[i], j = i - 1; - // 内循环:将 base 插入到左边的正确位置 - while (j >= 0 && nums[j] > base) { - nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位 - j--; - } - nums[j + 1] = base; // 2. 将 base 赋值到正确位置 - } - } + [class]{}-[func]{insertionSort} ``` === "TypeScript" ```typescript title="insertion_sort.ts" - /* 插入排序 */ - function insertionSort(nums: number[]): void { - // 外循环:base = nums[1], nums[2], ..., nums[n-1] - for (let i = 1; i < nums.length; i++) { - const base = nums[i]; - let j = i - 1; - // 内循环:将 base 插入到左边的正确位置 - while (j >= 0 && nums[j] > base) { - nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位 - j--; - } - nums[j + 1] = base; // 2. 将 base 赋值到正确位置 - } - } + [class]{}-[func]{insertionSort} ``` === "C" diff --git a/docs/chapter_sorting/quick_sort.md b/docs/chapter_sorting/quick_sort.md index a2b291867..25da0a856 100755 --- a/docs/chapter_sorting/quick_sort.md +++ b/docs/chapter_sorting/quick_sort.md @@ -108,7 +108,7 @@ comments: true === "JavaScript" - ``` js title="quick_sort.js" + ```javascript title="quick_sort.js" /* 元素交换 */ function swap(nums, i, j) { let tmp = nums[i]; @@ -288,33 +288,13 @@ comments: true === "JavaScript" ```javascript title="quick_sort.js" - /* 快速排序 */ - function quickSort(nums, left, right) { - // 子数组长度为 1 时终止递归 - if (left >= right) return; - // 哨兵划分 - const pivot = partition(nums, left, right); - // 递归左子数组、右子数组 - quickSort(nums, left, pivot - 1); - quickSort(nums, pivot + 1, right); - } + [class]{QuickSort}-[func]{quickSort} ``` === "TypeScript" ```typescript title="quick_sort.ts" - /* 快速排序 */ - function quickSort(nums: number[], left: number, right: number): void { - // 子数组长度为 1 时终止递归 - if (left >= right) { - return; - } - // 哨兵划分 - const pivot = partition(nums, left, right); - // 递归左子数组、右子数组 - quickSort(nums, left, pivot - 1); - quickSort(nums, pivot + 1, right); - } + [class]{QuickSort}-[func]{quickSort} ``` === "C" @@ -445,53 +425,17 @@ comments: true === "JavaScript" ```javascript title="quick_sort.js" - /* 选取三个元素的中位数 */ - function medianThree(nums, left, mid, right) { - // 使用了异或操作来简化代码 - // 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1 - if ((nums[left] < nums[mid]) ^ (nums[left] < nums[right])) - return left; - else if ((nums[mid] < nums[left]) ^ (nums[mid] < nums[right])) - return mid; - else - return right; - } - - /* 哨兵划分(三数取中值) */ - function partition(nums, left, right) { - // 选取三个候选元素的中位数 - let med = medianThree(nums, left, Math.floor((left + right) / 2), right); - // 将中位数交换至数组最左端 - swap(nums, left, med); - // 以 nums[left] 作为基准数 - // 下同省略... - } + [class]{QuickSortMedian}-[func]{medianThree} + + [class]{QuickSortMedian}-[func]{partition} ``` === "TypeScript" ```typescript title="quick_sort.ts" - /* 选取三个元素的中位数 */ - function medianThree(nums: number[], left: number, mid: number, right: number): number { - // 使用了异或操作来简化代码 - // 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1 - if (Number(nums[left] < nums[mid]) ^ Number(nums[left] < nums[right])) { - return left; - } else if (Number(nums[mid] < nums[left]) ^ Number(nums[mid] < nums[right])) { - return mid; - } else { - return right; - } - } + [class]{QuickSortMedian}-[func]{medianThree} - /* 哨兵划分(三数取中值) */ - function partition(nums: number[], left: number, right: number): number { - // 选取三个候选元素的中位数 - let med = medianThree(nums, left, Math.floor((left + right) / 2), right); - // 将中位数交换至数组最左端 - swap(nums, left, med); - // 以 nums[left] 作为基准数 - // 下同省略... + [class]{QuickSortMedian}-[func]{partition} ``` === "C" @@ -607,43 +551,13 @@ comments: true === "JavaScript" ```javascript title="quick_sort.js" - /* 快速排序(尾递归优化) */ - function quickSort(nums, left, right) { - // 子数组长度为 1 时终止 - while (left < right) { - // 哨兵划分操作 - let pivot = partition(nums, left, right); - // 对两个子数组中较短的那个执行快排 - if (pivot - left < right - pivot) { - quickSort(nums, left, pivot - 1); // 递归排序左子数组 - left = pivot + 1; // 剩余待排序区间为 [pivot + 1, right] - } else { - quickSort(nums, pivot + 1, right); // 递归排序右子数组 - right = pivot - 1; // 剩余待排序区间为 [left, pivot - 1] - } - } - } + [class]{QuickSortTailCall}-[func]{quickSort} ``` === "TypeScript" ```typescript title="quick_sort.ts" - /* 快速排序(尾递归优化) */ - function quickSort(nums: number[], left: number, right: number): void { - // 子数组长度为 1 时终止 - while (left < right) { - // 哨兵划分操作 - let pivot = partition(nums, left, right); - // 对两个子数组中较短的那个执行快排 - if (pivot - left < right - pivot) { - quickSort(nums, left, pivot - 1); // 递归排序左子数组 - left = pivot + 1; // 剩余待排序区间为 [pivot + 1, right] - } else { - quickSort(nums, pivot + 1, right); // 递归排序右子数组 - right = pivot - 1; // 剩余待排序区间为 [left, pivot - 1] - } - } - } + [class]{QuickSortTailCall}-[func]{quickSort} ``` === "C" diff --git a/docs/chapter_stack_and_queue/queue.md b/docs/chapter_stack_and_queue/queue.md index 339e5b36a..e610f234b 100755 --- a/docs/chapter_stack_and_queue/queue.md +++ b/docs/chapter_stack_and_queue/queue.md @@ -353,107 +353,13 @@ comments: true === "JavaScript" ```javascript title="linkedlist_queue.js" - /* 基于链表实现的队列 */ - class LinkedListQueue { - #front; // 头结点 #front - #rear; // 尾结点 #rear - #queSize = 0; - constructor() { - this.#front = null; - this.#rear = null; - } - /* 获取队列的长度 */ - get size() { - return this.#queSize; - } - /* 判断队列是否为空 */ - isEmpty() { - return this.size === 0; - } - /* 入队 */ - push(num) { - // 尾结点后添加 num - const node = new ListNode(num); - // 如果队列为空,则令头、尾结点都指向该结点 - if (!this.#front) { - this.#front = node; - this.#rear = node; - // 如果队列不为空,则将该结点添加到尾结点后 - } else { - this.#rear.next = node; - this.#rear = node; - } - this.#queSize++; - } - /* 出队 */ - poll() { - const num = this.peek(); - // 删除头结点 - this.#front = this.#front.next; - this.#queSize--; - return num; - } - /* 访问队首元素 */ - peek() { - if (this.size === 0) - throw new Error("队列为空"); - return this.#front.val; - } - } + [class]{LinkedListQueue}-[func]{} ``` === "TypeScript" ```typescript title="linkedlist_queue.ts" - /* 基于链表实现的队列 */ - class LinkedListQueue { - private front: ListNode | null; // 头结点 front - private rear: ListNode | null; // 尾结点 rear - private queSize: number = 0; - constructor() { - this.front = null; - this.rear = null; - } - /* 获取队列的长度 */ - get size(): number { - return this.queSize; - } - /* 判断队列是否为空 */ - isEmpty(): boolean { - return this.size === 0; - } - /* 入队 */ - push(num: number): void { - // 尾结点后添加 num - const node = new ListNode(num); - // 如果队列为空,则令头、尾结点都指向该结点 - if (!this.front) { - this.front = node; - this.rear = node; - // 如果队列不为空,则将该结点添加到尾结点后 - } else { - this.rear!.next = node; - this.rear = node; - } - this.queSize++; - } - /* 出队 */ - poll(): number { - const num = this.peek(); - if (!this.front) - throw new Error("队列为空") - // 删除头结点 - this.front = this.front.next; - this.queSize--; - return num; - } - /* 访问队首元素 */ - peek(): number { - if (this.size === 0) - throw new Error("队列为空"); - return this.front!.val; - } - } + [class]{LinkedListQueue}-[func]{} ``` === "C" @@ -698,122 +604,13 @@ comments: true === "JavaScript" ```javascript title="array_queue.js" - /* 基于环形数组实现的队列 */ - class ArrayQueue { - #nums; // 用于存储队列元素的数组 - #front = 0; // 队首指针,指向队首元素 - #queSize = 0; // 队列长度 - - constructor(capacity) { - this.#nums = new Array(capacity); - } - - /* 获取队列的容量 */ - get capacity() { - return this.#nums.length; - } - - /* 获取队列的长度 */ - get size() { - return this.#queSize; - } - - /* 判断队列是否为空 */ - empty() { - return this.#queSize == 0; - } - - /* 入队 */ - push(num) { - if (this.size == this.capacity) { - console.log("队列已满"); - return; - } - // 计算尾指针,指向队尾索引 + 1 - // 通过取余操作,实现 rear 越过数组尾部后回到头部 - const rear = (this.#front + this.size) % this.capacity; - // 尾结点后添加 num - this.#nums[rear] = num; - this.#queSize++; - } - - /* 出队 */ - poll() { - const num = this.peek(); - // 队首指针向后移动一位,若越过尾部则返回到数组头部 - this.#front = (this.#front + 1) % this.capacity; - this.#queSize--; - return num; - } - - /* 访问队首元素 */ - peek() { - if (this.empty()) - throw new Error("队列为空"); - return this.#nums[this.#front]; - } - } + [class]{ArrayQueue}-[func]{} ``` === "TypeScript" ```typescript title="array_queue.ts" - /* 基于环形数组实现的队列 */ - class ArrayQueue { - private nums: number[]; // 用于存储队列元素的数组 - private front: number; // 队首指针,指向队首元素 - private queSize: number; // 队列长度 - - constructor(capacity: number) { - this.nums = new Array(capacity); - this.front = this.queSize = 0; - } - - /* 获取队列的容量 */ - get capacity(): number { - return this.nums.length; - } - - /* 获取队列的长度 */ - get size(): number { - return this.queSize; - } - - /* 判断队列是否为空 */ - empty(): boolean { - return this.queSize == 0; - } - - /* 入队 */ - push(num: number): void { - if (this.size == this.capacity) { - console.log("队列已满"); - return; - } - // 计算尾指针,指向队尾索引 + 1 - // 通过取余操作,实现 rear 越过数组尾部后回到头部 - const rear = (this.front + this.queSize) % this.capacity; - // 尾结点后添加 num - this.nums[rear] = num; - this.queSize++; - } - - /* 出队 */ - poll(): number { - const num = this.peek(); - // 队首指针向后移动一位,若越过尾部则返回到数组头部 - this.front = (this.front + 1) % this.capacity; - this.queSize--; - return num; - } - - /* 访问队首元素 */ - peek(): number { - if (this.empty()) - throw new Error("队列为空"); - return this.nums[this.front]; - } - } + [class]{ArrayQueue}-[func]{} ``` === "C" diff --git a/docs/chapter_stack_and_queue/stack.md b/docs/chapter_stack_and_queue/stack.md index 9d1af73be..7bd531729 100755 --- a/docs/chapter_stack_and_queue/stack.md +++ b/docs/chapter_stack_and_queue/stack.md @@ -356,125 +356,13 @@ comments: true === "JavaScript" ```javascript title="linkedlist_stack.js" - /* 基于链表实现的栈 */ - class LinkedListStack { - #stackPeek; // 将头结点作为栈顶 - #stkSize = 0; // 栈的长度 - - constructor() { - this.#stackPeek = null; - } - - /* 获取栈的长度 */ - get size() { - return this.#stkSize; - } - - /* 判断栈是否为空 */ - isEmpty() { - return this.size == 0; - } - - /* 入栈 */ - push(num) { - const node = new ListNode(num); - node.next = this.#stackPeek; - this.#stackPeek = node; - this.#stkSize++; - } - - /* 出栈 */ - pop() { - const num = this.peek(); - if (!this.#stackPeek) { - throw new Error("栈为空!"); - } - this.#stackPeek = this.#stackPeek.next; - this.#stkSize--; - return num; - } - - /* 访问栈顶元素 */ - peek() { - if (!this.#stackPeek) { - throw new Error("栈为空!"); - } - return this.#stackPeek.val; - } - - /* 将链表转化为 Array 并返回 */ - toArray() { - let node = this.#stackPeek; - const res = new Array(this.size); - for (let i = res.length - 1; i >= 0; i--) { - res[i] = node.val; - node = node.next; - } - return res; - } - } + [class]{LinkedListStack}-[func]{} ``` === "TypeScript" ```typescript title="linkedlist_stack.ts" - /* 基于链表实现的栈 */ - class LinkedListStack { - private stackPeek: ListNode | null; // 将头结点作为栈顶 - private stkSize: number = 0; // 栈的长度 - - constructor() { - this.stackPeek = null; - } - - /* 获取栈的长度 */ - get size(): number { - return this.stkSize; - } - - /* 判断栈是否为空 */ - isEmpty(): boolean { - return this.size == 0; - } - - /* 入栈 */ - push(num: number): void { - const node = new ListNode(num); - node.next = this.stackPeek; - this.stackPeek = node; - this.stkSize++; - } - - /* 出栈 */ - pop(): number { - const num = this.peek(); - if (!this.stackPeek) { - throw new Error("栈为空!"); - } - this.stackPeek = this.stackPeek.next; - this.stkSize--; - return num; - } - - /* 访问栈顶元素 */ - peek(): number { - if (!this.stackPeek) { - throw new Error("栈为空!"); - } - return this.stackPeek.val; - } - - /* 将链表转化为 Array 并返回 */ - toArray(): number[] { - let node = this.stackPeek; - const res = new Array(this.size); - for (let i = res.length - 1; i >= 0; i--) { - res[i] = node!.val; - node = node!.next; - } - return res; - } - } + [class]{LinkedListStack}-[func]{} ``` === "C" @@ -672,73 +560,13 @@ comments: true === "JavaScript" ```javascript title="array_stack.js" - /* 基于数组实现的栈 */ - class ArrayStack { - stack; - constructor() { - this.stack = []; - } - /* 获取栈的长度 */ - get size() { - return this.stack.length; - } - /* 判断栈是否为空 */ - empty() { - return this.stack.length === 0; - } - /* 入栈 */ - push(num) { - this.stack.push(num); - } - /* 出栈 */ - pop() { - if (this.empty()) - throw new Error("栈为空"); - return this.stack.pop(); - } - /* 访问栈顶元素 */ - top() { - if (this.empty()) - throw new Error("栈为空"); - return this.stack[this.stack.length - 1]; - } - }; + [class]{ArrayStack}-[func]{} ``` === "TypeScript" ```typescript title="array_stack.ts" - /* 基于数组实现的栈 */ - class ArrayStack { - private stack: number[]; - constructor() { - this.stack = []; - } - /* 获取栈的长度 */ - get size(): number { - return this.stack.length; - } - /* 判断栈是否为空 */ - empty(): boolean { - return this.stack.length === 0; - } - /* 入栈 */ - push(num: number): void { - this.stack.push(num); - } - /* 出栈 */ - pop(): number | undefined { - if (this.empty()) - throw new Error('栈为空'); - return this.stack.pop(); - } - /* 访问栈顶元素 */ - top(): number | undefined { - if (this.empty()) - throw new Error('栈为空'); - return this.stack[this.stack.length - 1]; - } - }; + [class]{ArrayStack}-[func]{} ``` === "C" diff --git a/docs/chapter_tree/avl_tree.md b/docs/chapter_tree/avl_tree.md index f4336721c..22304f0ad 100755 --- a/docs/chapter_tree/avl_tree.md +++ b/docs/chapter_tree/avl_tree.md @@ -329,25 +329,13 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit === "JavaScript" ```javascript title="avl_tree.js" - /* 获取平衡因子 */ - balanceFactor(node) { - // 空结点平衡因子为 0 - if (node === null) return 0; - // 结点平衡因子 = 左子树高度 - 右子树高度 - return this.height(node.left) - this.height(node.right); - } + [class]{AVLTree}-[func]{balanceFactor} ``` === "TypeScript" ```typescript title="avl_tree.ts" - /* 获取平衡因子 */ - balanceFactor(node: TreeNode): number { - // 空结点平衡因子为 0 - if (node === null) return 0; - // 结点平衡因子 = 左子树高度 - 右子树高度 - return this.height(node.left) - this.height(node.right); - } + [class]{AVLTree}-[func]{balanceFactor} ``` === "C" @@ -460,37 +448,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "JavaScript" ```javascript title="avl_tree.js" - /* 右旋操作 */ - rightRotate(node) { - const child = node.left; - const grandChild = child.right; - // 以 child 为原点,将 node 向右旋转 - child.right = node; - node.left = grandChild; - // 更新结点高度 - this.updateHeight(node); - this.updateHeight(child); - // 返回旋转后子树的根结点 - return child; - } + [class]{AVLTree}-[func]{rightRotate} ``` === "TypeScript" ```typescript title="avl_tree.ts" - /* 右旋操作 */ - rightRotate(node: TreeNode): TreeNode { - const child = node.left; - const grandChild = child.right; - // 以 child 为原点,将 node 向右旋转 - child.right = node; - node.left = grandChild; - // 更新结点高度 - this.updateHeight(node); - this.updateHeight(child); - // 返回旋转后子树的根结点 - return child; - } + [class]{AVLTree}-[func]{rightRotate} ``` === "C" @@ -593,37 +557,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "JavaScript" ```javascript title="avl_tree.js" - /* 左旋操作 */ - leftRotate(node) { - const child = node.right; - const grandChild = child.left; - // 以 child 为原点,将 node 向左旋转 - child.left = node; - node.right = grandChild; - // 更新结点高度 - this.updateHeight(node); - this.updateHeight(child); - // 返回旋转后子树的根结点 - return child; - } + [class]{AVLTree}-[func]{leftRotate} ``` === "TypeScript" ```typescript title="avl_tree.ts" - /* 左旋操作 */ - leftRotate(node: TreeNode): TreeNode { - const child = node.right; - const grandChild = child.left; - // 以 child 为原点,将 node 向左旋转 - child.left = node; - node.right = grandChild; - // 更新结点高度 - this.updateHeight(node); - this.updateHeight(child); - // 返回旋转后子树的根结点 - return child; - } + [class]{AVLTree}-[func]{leftRotate} ``` === "C" @@ -767,69 +707,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影 === "JavaScript" ```javascript title="avl_tree.js" - /* 执行旋转操作,使该子树重新恢复平衡 */ - rotate(node) { - // 获取结点 node 的平衡因子 - const balanceFactor = this.balanceFactor(node); - // 左偏树 - if (balanceFactor > 1) { - if (this.balanceFactor(node.left) >= 0) { - // 右旋 - return this.rightRotate(node); - } else { - // 先左旋后右旋 - node.left = this.leftRotate(node.left); - return this.rightRotate(node); - } - } - // 右偏树 - if (balanceFactor < -1) { - if (this.balanceFactor(node.right) <= 0) { - // 左旋 - return this.leftRotate(node); - } else { - // 先右旋后左旋 - node.right = this.rightRotate(node.right); - return this.leftRotate(node); - } - } - // 平衡树,无需旋转,直接返回 - return node; - } + [class]{AVLTree}-[func]{rotate} ``` === "TypeScript" ```typescript title="avl_tree.ts" - /* 执行旋转操作,使该子树重新恢复平衡 */ - rotate(node: TreeNode): TreeNode { - // 获取结点 node 的平衡因子 - const balanceFactor = this.balanceFactor(node); - // 左偏树 - if (balanceFactor > 1) { - if (this.balanceFactor(node.left) >= 0) { - // 右旋 - return this.rightRotate(node); - } else { - // 先左旋后右旋 - node.left = this.leftRotate(node.left); - return this.rightRotate(node); - } - } - // 右偏树 - if (balanceFactor < -1) { - if (this.balanceFactor(node.right) <= 0) { - // 左旋 - return this.leftRotate(node); - } else { - // 先右旋后左旋 - node.right = this.rightRotate(node.right); - return this.leftRotate(node); - } - } - // 平衡树,无需旋转,直接返回 - return node; - } + [class]{AVLTree}-[func]{rotate} ``` === "C" diff --git a/docs/chapter_tree/binary_search_tree.md b/docs/chapter_tree/binary_search_tree.md index 531941994..081b41089 100755 --- a/docs/chapter_tree/binary_search_tree.md +++ b/docs/chapter_tree/binary_search_tree.md @@ -80,42 +80,13 @@ comments: true === "JavaScript" ```javascript title="binary_search_tree.js" - /* 查找结点 */ - function search(num) { - let cur = root; - // 循环查找,越过叶结点后跳出 - while (cur !== null) { - // 目标结点在 cur 的右子树中 - if (cur.val < num) cur = cur.right; - // 目标结点在 cur 的左子树中 - else if (cur.val > num) cur = cur.left; - // 找到目标结点,跳出循环 - else break; - } - // 返回目标结点 - return cur; - } + [class]{}-[func]{search} ``` === "TypeScript" ```typescript title="binary_search_tree.ts" - /* 查找结点 */ - function search(num: number): TreeNode | null { - let cur = root; - // 循环查找,越过叶结点后跳出 - while (cur !== null) { - if (cur.val < num) { - cur = cur.right; // 目标结点在 cur 的右子树中 - } else if (cur.val > num) { - cur = cur.left; // 目标结点在 cur 的左子树中 - } else { - break; // 找到目标结点,跳出循环 - } - } - // 返回目标结点 - return cur; - } + [class]{}-[func]{search} ``` === "C" @@ -245,61 +216,13 @@ comments: true === "JavaScript" ```javascript title="binary_search_tree.js" - /* 插入结点 */ - function insert(num) { - // 若树为空,直接提前返回 - if (root === null) return null; - let cur = root, pre = null; - // 循环查找,越过叶结点后跳出 - while (cur !== null) { - // 找到重复结点,直接返回 - if (cur.val === num) return null; - pre = cur; - // 插入位置在 cur 的右子树中 - if (cur.val < num) cur = cur.right; - // 插入位置在 cur 的左子树中 - else cur = cur.left; - } - // 插入结点 val - let node = new Tree.TreeNode(num); - if (pre.val < num) pre.right = node; - else pre.left = node; - return node; - } + [class]{}-[func]{insert} ``` === "TypeScript" ```typescript title="binary_search_tree.ts" - /* 插入结点 */ - function insert(num: number): TreeNode | null { - // 若树为空,直接提前返回 - if (root === null) { - return null; - } - let cur = root, - pre: TreeNode | null = null; - // 循环查找,越过叶结点后跳出 - while (cur !== null) { - if (cur.val === num) { - return null; // 找到重复结点,直接返回 - } - pre = cur; - if (cur.val < num) { - cur = cur.right as TreeNode; // 插入位置在 cur 的右子树中 - } else { - cur = cur.left as TreeNode; // 插入位置在 cur 的左子树中 - } - } - // 插入结点 val - let node = new TreeNode(num); - if (pre!.val < num) { - pre!.right = node; - } else { - pre!.left = node; - } - return node; - } + [class]{}-[func]{insert} ``` === "C" @@ -518,118 +441,17 @@ comments: true === "JavaScript" ```javascript title="binary_search_tree.js" - /* 删除结点 */ - function remove(num) { - // 若树为空,直接提前返回 - if (root === null) return null; - let cur = root, pre = null; - // 循环查找,越过叶结点后跳出 - while (cur !== null) { - // 找到待删除结点,跳出循环 - if (cur.val === num) break; - pre = cur; - // 待删除结点在 cur 的右子树中 - if (cur.val < num) cur = cur.right; - // 待删除结点在 cur 的左子树中 - else cur = cur.left; - } - // 若无待删除结点,则直接返回 - if (cur === null) return null; - // 子结点数量 = 0 or 1 - if (cur.left === null || cur.right === null) { - // 当子结点数量 = 0 / 1 时, child = null / 该子结点 - let child = cur.left !== null ? cur.left : cur.right; - // 删除结点 cur - if (pre.left === cur) pre.left = child; - else pre.right = child; - } - // 子结点数量 = 2 - else { - // 获取中序遍历中 cur 的下一个结点 - let nex = getInOrderNext(cur.right); - let tmp = nex.val; - // 递归删除结点 nex - remove(nex.val); - // 将 nex 的值复制给 cur - cur.val = tmp; - } - return cur; - } + [class]{}-[func]{remove} - /* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ - function getInOrderNext(root) { - if (root === null) return root; - // 循环访问左子结点,直到叶结点时为最小结点,跳出 - while (root.left !== null) { - root = root.left; - } - return root; - } + [class]{}-[func]{getInOrderNext} ``` === "TypeScript" ```typescript title="binary_search_tree.ts" - /* 删除结点 */ - function remove(num: number): TreeNode | null { - // 若树为空,直接提前返回 - if (root === null) { - return null; - } - let cur = root, - pre: TreeNode | null = null; - // 循环查找,越过叶结点后跳出 - while (cur !== null) { - // 找到待删除结点,跳出循环 - if (cur.val === num) { - break; - } - pre = cur; - if (cur.val < num) { - cur = cur.right as TreeNode; // 待删除结点在 cur 的右子树中 - } else { - cur = cur.left as TreeNode; // 待删除结点在 cur 的左子树中 - } - } - // 若无待删除结点,则直接返回 - if (cur === null) { - return null; - } - // 子结点数量 = 0 or 1 - if (cur.left === null || cur.right === null) { - // 当子结点数量 = 0 / 1 时, child = null / 该子结点 - let child = cur.left !== null ? cur.left : cur.right; - // 删除结点 cur - if (pre!.left === cur) { - pre!.left = child; - } else { - pre!.right = child; - } - } - // 子结点数量 = 2 - else { - // 获取中序遍历中 cur 的下一个结点 - let next = getInOrderNext(cur.right); - let tmp = next!.val; - // 递归删除结点 nex - remove(next!.val); - // 将 nex 的值复制给 cur - cur.val = tmp; - } - return cur; - } + [class]{}-[func]{remove} - /* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */ - function getInOrderNext(root: TreeNode | null): TreeNode | null { - if (root === null) { - return null; - } - // 循环访问左子结点,直到叶结点时为最小结点,跳出 - while (root.left !== null) { - root = root.left; - } - return root; - } + [class]{}-[func]{getInOrderNext} ``` === "C" diff --git a/docs/chapter_tree/binary_tree_traversal.md b/docs/chapter_tree/binary_tree_traversal.md index 1760bf443..ab452f50a 100755 --- a/docs/chapter_tree/binary_tree_traversal.md +++ b/docs/chapter_tree/binary_tree_traversal.md @@ -67,45 +67,13 @@ comments: true === "JavaScript" ```javascript title="binary_tree_bfs.js" - /* 层序遍历 */ - function hierOrder(root) { - // 初始化队列,加入根结点 - let queue = [root]; - // 初始化一个列表,用于保存遍历序列 - let list = []; - while (queue.length) { - let node = queue.shift(); // 队列出队 - list.push(node.val); // 保存结点值 - if (node.left) - queue.push(node.left); // 左子结点入队 - if (node.right) - queue.push(node.right); // 右子结点入队 - } - return list; - } + [class]{}-[func]{hierOrder} ``` === "TypeScript" ```typescript title="binary_tree_bfs.ts" - /* 层序遍历 */ - function hierOrder(root: TreeNode | null): number[] { - // 初始化队列,加入根结点 - const queue = [root]; - // 初始化一个列表,用于保存遍历序列 - const list: number[] = []; - while (queue.length) { - let node = queue.shift() as TreeNode; // 队列出队 - list.push(node.val); // 保存结点值 - if (node.left) { - queue.push(node.left); // 左子结点入队 - } - if (node.right) { - queue.push(node.right); // 右子结点入队 - } - } - return list; - } + [class]{}-[func]{hierOrder} ``` === "C" @@ -258,69 +226,21 @@ comments: true === "JavaScript" ```javascript title="binary_tree_dfs.js" - /* 前序遍历 */ - function preOrder(root){ - if (root === null) return; - // 访问优先级:根结点 -> 左子树 -> 右子树 - list.push(root.val); - preOrder(root.left); - preOrder(root.right); - } - - /* 中序遍历 */ - function inOrder(root) { - if (root === null) return; - // 访问优先级:左子树 -> 根结点 -> 右子树 - inOrder(root.left); - list.push(root.val); - inOrder(root.right); - } - - /* 后序遍历 */ - function postOrder(root) { - if (root === null) return; - // 访问优先级:左子树 -> 右子树 -> 根结点 - postOrder(root.left); - postOrder(root.right); - list.push(root.val); - } + [class]{}-[func]{preOrder} + + [class]{}-[func]{inOrder} + + [class]{}-[func]{postOrder} ``` === "TypeScript" ```typescript title="binary_tree_dfs.ts" - /* 前序遍历 */ - function preOrder(root: TreeNode | null): void { - if (root === null) { - return; - } - // 访问优先级:根结点 -> 左子树 -> 右子树 - list.push(root.val); - preOrder(root.left); - preOrder(root.right); - } - - /* 中序遍历 */ - function inOrder(root: TreeNode | null): void { - if (root === null) { - return; - } - // 访问优先级:左子树 -> 根结点 -> 右子树 - inOrder(root.left); - list.push(root.val); - inOrder(root.right); - } - - /* 后序遍历 */ - function postOrder(root: TreeNode | null): void { - if (root === null) { - return; - } - // 访问优先级:左子树 -> 右子树 -> 根结点 - postOrder(root.left); - postOrder(root.right); - list.push(root.val); - } + [class]{}-[func]{preOrder} + + [class]{}-[func]{inOrder} + + [class]{}-[func]{postOrder} ``` === "C" diff --git a/docs/utils/deploy.sh b/docs/utils/deploy.sh index fb269ea00..6f3e68b5a 100644 --- a/docs/utils/deploy.sh +++ b/docs/utils/deploy.sh @@ -1,8 +1,14 @@ # This script is borrowed from https://gist.github.com/cobyism/4730490 -git add build && git commit -m "build" -git subtree push --prefix build origin built-docs +cd build +git add . +git commit -m "build" +git push -u origin docs +cd .. mkdocs build --clean -git add site && git commit -m "deploy" -git subtree push --prefix site origin gh-pages + +cd site +git add . +git commit -m "deploy" +git push -u origin gh-pages diff --git a/docs/utils/extract_code_jsts.py b/docs/utils/extract_code_jsts.py index 3458ed55d..f14a45fbb 100644 --- a/docs/utils/extract_code_jsts.py +++ b/docs/utils/extract_code_jsts.py @@ -16,10 +16,10 @@ class ExtractCodeBlocksJSTS(ExtractCodeBlocksJava): super().__init__() # Pattern to match function names and class names - self.func_pattern = r'\s*(function|private|public|)\s*(\S*)\(.*\)(:|)\s*(\S*)\s*{\s*\n' + self.func_pattern = r'(\s*)(function|private|public|)\s*(\S*)\(.*\)(:|)\s*(.*)\s+{\s*\n' self.class_pattern = r'class\s+(\w+)\s*\{' - self.func_pattern_keys = ["total", "prefix", "label", ":", "return"] + self.func_pattern_keys = ["total", "ind", "prefix", "label", ":", "return"] self.class_pattern_keys = ["total", "label"]