diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 774d2773f..68be3e70b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,6 +1,4 @@ -> Tip: If this PR is not related to the coding or code translation, please ignore the checklist. - -### Checklist +If this PR is related to coding or code translation, please fill out the checklist. - [ ] I've tested the code and ensured the outputs are the same as the outputs of reference codes. - [ ] I've checked the codes (formatting, comments, indentation, file header, etc) carefully. diff --git a/README.md b/README.md index 6a6e165d7..560e73953 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ - 开源免费,所有同学都可在网上获取本书; - 新手友好,适合算法初学者自主学习入门; - 动画讲解,尽可能地保证平滑的学习曲线; -- 代码导向,提供精简、可运行的算法代码; +- 代码导向,提供可一键运行的算法源代码; - 讨论学习,提问一般能在三日内得到回复; 如果感觉本书对你有所帮助,请点个 Star :star: 支持一下,谢谢! diff --git a/codes/javascript/chapter_searching/binary_search.js b/codes/javascript/chapter_searching/binary_search.js new file mode 100644 index 000000000..3cca17884 --- /dev/null +++ b/codes/javascript/chapter_searching/binary_search.js @@ -0,0 +1,53 @@ +/** + * File: binary_search.js + * Created Time: 2022-12-22 + * Author: JoseHung (szhong@link.cuhk.edu.hk) + */ + +/* 二分查找(双闭区间) */ +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; +} + +/* 二分查找(左闭右开) */ +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; +} + +/* Driver Code */ +var target = 6; +var nums = [1, 3, 6, 8, 12, 15, 23, 67, 70, 92]; + +/* 二分查找(双闭区间) */ +var index = binarySearch(nums, target); +console.log("目标元素 6 的索引 = " + index); + +/* 二分查找(左闭右开) */ +index = binarySearch1(nums, target); +console.log("目标元素 6 的索引 = " + index); diff --git a/codes/javascript/chapter_searching/linear_search.js b/codes/javascript/chapter_searching/linear_search.js new file mode 100644 index 000000000..b71f0cede --- /dev/null +++ b/codes/javascript/chapter_searching/linear_search.js @@ -0,0 +1,48 @@ +/** + * File: linear-search.js + * Created Time: 2022-12-22 + * Author: JoseHung (szhong@link.cuhk.edu.hk) + */ + +const ListNode = require("../include/ListNode"); + +/* 线性查找(数组) */ +function linearSearchArray(nums, target) { + // 遍历数组 + for (let i = 0; i < nums.length; i++) { + // 找到目标元素,返回其索引 + if (nums[i] === target) { + return i; + } + } + // 未找到目标元素,返回 -1 + return -1; +} + +/* 线性查找(链表)*/ +function linearSearchLinkedList(head, target) { + // 遍历链表 + while(head) { + // 找到目标结点,返回之 + if(head.val === target) { + return head; + } + head = head.next; + } + // 未找到目标结点,返回 null + return null; +} + +/* Driver Code */ +var target = 3; + +/* 在数组中执行线性查找 */ +var nums = [1, 5, 3, 2, 4, 7, 5, 9, 10, 8]; +var index = linearSearchArray(nums, target); +console.log("目标元素 3 的索引 = " + index); + +/* 在链表中执行线性查找 */ +var linkedList = new ListNode(); +var head = linkedList.arrToLinkedList(nums); +var node = linearSearchLinkedList(head, target); +console.log("目标结点值 3 的对应结点对象为 " + node); diff --git a/codes/javascript/include/ListNode.js b/codes/javascript/include/ListNode.js index 72306548c..6e226e9c3 100755 --- a/codes/javascript/include/ListNode.js +++ b/codes/javascript/include/ListNode.js @@ -22,7 +22,7 @@ class ListNode { */ arrToLinkedList(arr) { const dum = new ListNode(0); - const head = dum; + let head = dum; for (const val of arr) { head.next = new ListNode(val); head = head.next; diff --git a/codes/python/chapter_array_and_linkedlist/array.py b/codes/python/chapter_array_and_linkedlist/array.py index 7f34472c7..8933fb482 100644 --- a/codes/python/chapter_array_and_linkedlist/array.py +++ b/codes/python/chapter_array_and_linkedlist/array.py @@ -1,8 +1,8 @@ -''' +""" File: array.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_array_and_linkedlist/linked_list.py b/codes/python/chapter_array_and_linkedlist/linked_list.py index d176d8dd2..dce110340 100644 --- a/codes/python/chapter_array_and_linkedlist/linked_list.py +++ b/codes/python/chapter_array_and_linkedlist/linked_list.py @@ -1,8 +1,8 @@ -''' +""" File: linked_list.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_array_and_linkedlist/list.py b/codes/python/chapter_array_and_linkedlist/list.py index ac71b98b8..b0e2f2536 100644 --- a/codes/python/chapter_array_and_linkedlist/list.py +++ b/codes/python/chapter_array_and_linkedlist/list.py @@ -1,8 +1,8 @@ -''' +""" File: list.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_array_and_linkedlist/my_list.py b/codes/python/chapter_array_and_linkedlist/my_list.py index 077fc0ce5..550e66955 100644 --- a/codes/python/chapter_array_and_linkedlist/my_list.py +++ b/codes/python/chapter_array_and_linkedlist/my_list.py @@ -1,8 +1,8 @@ -''' +""" File: my_list.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_computational_complexity/leetcode_two_sum.py b/codes/python/chapter_computational_complexity/leetcode_two_sum.py index 182caec39..cb3bf3b02 100644 --- a/codes/python/chapter_computational_complexity/leetcode_two_sum.py +++ b/codes/python/chapter_computational_complexity/leetcode_two_sum.py @@ -1,8 +1,8 @@ -''' +""" File: leetcode_two_sum.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_computational_complexity/space_complexity.py b/codes/python/chapter_computational_complexity/space_complexity.py index 69c1ac015..7efe8d948 100644 --- a/codes/python/chapter_computational_complexity/space_complexity.py +++ b/codes/python/chapter_computational_complexity/space_complexity.py @@ -1,8 +1,8 @@ -''' +""" File: space_complexity.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_computational_complexity/time_complexity.py b/codes/python/chapter_computational_complexity/time_complexity.py index a3e698384..bfb5b3b11 100644 --- a/codes/python/chapter_computational_complexity/time_complexity.py +++ b/codes/python/chapter_computational_complexity/time_complexity.py @@ -1,8 +1,8 @@ -''' +""" File: time_complexity.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_computational_complexity/worst_best_time_complexity.py b/codes/python/chapter_computational_complexity/worst_best_time_complexity.py index 7b052a3e0..b70dce4f0 100644 --- a/codes/python/chapter_computational_complexity/worst_best_time_complexity.py +++ b/codes/python/chapter_computational_complexity/worst_best_time_complexity.py @@ -1,8 +1,8 @@ -''' +""" File: worst_best_time_complexity.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_searching/binary_search.py b/codes/python/chapter_searching/binary_search.py index 3d9ee0ffc..275ae28ec 100644 --- a/codes/python/chapter_searching/binary_search.py +++ b/codes/python/chapter_searching/binary_search.py @@ -1,8 +1,8 @@ -''' +""" File: binary_search.py Created Time: 2022-11-26 Author: timi (xisunyy@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_searching/hashing_search.py b/codes/python/chapter_searching/hashing_search.py index 68cffe64a..f49c703be 100644 --- a/codes/python/chapter_searching/hashing_search.py +++ b/codes/python/chapter_searching/hashing_search.py @@ -1,8 +1,8 @@ -''' +""" File: hashing_search.py Created Time: 2022-11-26 Author: timi (xisunyy@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_searching/linear_search.py b/codes/python/chapter_searching/linear_search.py index 933095653..8ff9e0803 100644 --- a/codes/python/chapter_searching/linear_search.py +++ b/codes/python/chapter_searching/linear_search.py @@ -1,8 +1,8 @@ -''' +""" File: linear_search.py Created Time: 2022-11-26 Author: timi (xisunyy@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_sorting/bubble_sort.py b/codes/python/chapter_sorting/bubble_sort.py index 54260dd96..610e3186c 100644 --- a/codes/python/chapter_sorting/bubble_sort.py +++ b/codes/python/chapter_sorting/bubble_sort.py @@ -1,8 +1,8 @@ -''' +""" File: bubble_sort.py Created Time: 2022-11-25 Author: timi (xisunyy@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_sorting/insertion_sort.py b/codes/python/chapter_sorting/insertion_sort.py index db85515d1..bf8492cdd 100644 --- a/codes/python/chapter_sorting/insertion_sort.py +++ b/codes/python/chapter_sorting/insertion_sort.py @@ -1,8 +1,8 @@ -''' +""" File: insertion_sort.py Created Time: 2022-11-25 Author: timi (xisunyy@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_sorting/merge_sort.py b/codes/python/chapter_sorting/merge_sort.py index 533fb9de7..f3fb538ae 100644 --- a/codes/python/chapter_sorting/merge_sort.py +++ b/codes/python/chapter_sorting/merge_sort.py @@ -1,8 +1,8 @@ -''' +""" File: merge_sort.py Created Time: 2022-11-25 Author: timi (xisunyy@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_sorting/quick_sort.py b/codes/python/chapter_sorting/quick_sort.py index 5ba826bfa..f5ce8120c 100644 --- a/codes/python/chapter_sorting/quick_sort.py +++ b/codes/python/chapter_sorting/quick_sort.py @@ -1,8 +1,8 @@ -''' +""" File: quick_sort.py Created Time: 2022-11-25 Author: timi (xisunyy@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_stack_and_queue/array_queue.py b/codes/python/chapter_stack_and_queue/array_queue.py index 7408f2ba2..947c06091 100644 --- a/codes/python/chapter_stack_and_queue/array_queue.py +++ b/codes/python/chapter_stack_and_queue/array_queue.py @@ -1,8 +1,8 @@ -''' +""" File: array_queue.py Created Time: 2022-12-01 Author: Peng Chen (pengchzn@gmail.com) -''' +""" import os.path as osp import sys diff --git a/codes/python/chapter_stack_and_queue/array_stack.py b/codes/python/chapter_stack_and_queue/array_stack.py index 889a372dc..18aee16b0 100644 --- a/codes/python/chapter_stack_and_queue/array_stack.py +++ b/codes/python/chapter_stack_and_queue/array_stack.py @@ -1,8 +1,8 @@ -''' +""" File: array_stack.py Created Time: 2022-11-29 Author: Peng Chen (pengchzn@gmail.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_stack_and_queue/deque.py b/codes/python/chapter_stack_and_queue/deque.py index 7881a965e..30444c6b3 100644 --- a/codes/python/chapter_stack_and_queue/deque.py +++ b/codes/python/chapter_stack_and_queue/deque.py @@ -1,8 +1,8 @@ -''' +""" File: deque.py Created Time: 2022-11-29 Author: Peng Chen (pengchzn@gmail.com) -''' +""" import os.path as osp import sys diff --git a/codes/python/chapter_stack_and_queue/linkedlist_queue.py b/codes/python/chapter_stack_and_queue/linkedlist_queue.py index 0d4a28d4d..2ab7196d3 100644 --- a/codes/python/chapter_stack_and_queue/linkedlist_queue.py +++ b/codes/python/chapter_stack_and_queue/linkedlist_queue.py @@ -1,8 +1,8 @@ -''' +""" File: linkedlist_queue.py Created Time: 2022-12-01 Author: Peng Chen (pengchzn@gmail.com) -''' +""" import os.path as osp import sys diff --git a/codes/python/chapter_stack_and_queue/linkedlist_stack.py b/codes/python/chapter_stack_and_queue/linkedlist_stack.py index 5ee90353b..21f6ca6af 100644 --- a/codes/python/chapter_stack_and_queue/linkedlist_stack.py +++ b/codes/python/chapter_stack_and_queue/linkedlist_stack.py @@ -1,8 +1,8 @@ -''' +""" File: linkedlist_stack.py Created Time: 2022-11-29 Author: Peng Chen (pengchzn@gmail.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_stack_and_queue/queue.py b/codes/python/chapter_stack_and_queue/queue.py index 740d9b1e1..ce220d7c1 100644 --- a/codes/python/chapter_stack_and_queue/queue.py +++ b/codes/python/chapter_stack_and_queue/queue.py @@ -1,8 +1,8 @@ -''' +""" File: queue.py Created Time: 2022-11-29 Author: Peng Chen (pengchzn@gmail.com) -''' +""" import os.path as osp import sys diff --git a/codes/python/chapter_stack_and_queue/stack.py b/codes/python/chapter_stack_and_queue/stack.py index a8d2a7a50..5e95258fe 100644 --- a/codes/python/chapter_stack_and_queue/stack.py +++ b/codes/python/chapter_stack_and_queue/stack.py @@ -1,8 +1,8 @@ -''' +""" File: stack.py Created Time: 2022-11-29 Author: Peng Chen (pengchzn@gmail.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_tree/binary_search_tree.py b/codes/python/chapter_tree/binary_search_tree.py index f9dd9ec95..0f855f279 100644 --- a/codes/python/chapter_tree/binary_search_tree.py +++ b/codes/python/chapter_tree/binary_search_tree.py @@ -1,8 +1,8 @@ -''' +""" File: binary_search_tree.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_tree/binary_tree.py b/codes/python/chapter_tree/binary_tree.py index 78afa868e..81828b5cf 100644 --- a/codes/python/chapter_tree/binary_tree.py +++ b/codes/python/chapter_tree/binary_tree.py @@ -1,8 +1,8 @@ -''' +""" File: binary_tree.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_tree/binary_tree_bfs.py b/codes/python/chapter_tree/binary_tree_bfs.py index 43f192206..9ae1b3594 100644 --- a/codes/python/chapter_tree/binary_tree_bfs.py +++ b/codes/python/chapter_tree/binary_tree_bfs.py @@ -1,8 +1,8 @@ -''' +""" File: binary_tree_bfs.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/chapter_tree/binary_tree_dfs.py b/codes/python/chapter_tree/binary_tree_dfs.py index f8415ef56..094bd4cb5 100644 --- a/codes/python/chapter_tree/binary_tree_dfs.py +++ b/codes/python/chapter_tree/binary_tree_dfs.py @@ -1,8 +1,8 @@ -''' +""" File: binary_tree_dfs.py Created Time: 2022-11-25 Author: Krahets (krahets@163.com) -''' +""" import sys, os.path as osp sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) diff --git a/codes/python/include/binary_tree.py b/codes/python/include/binary_tree.py index 24acb47d4..de2569e42 100644 --- a/codes/python/include/binary_tree.py +++ b/codes/python/include/binary_tree.py @@ -1,8 +1,8 @@ -''' +""" File: binary_tree.py Created Time: 2021-12-11 Author: Krahets (krahets@163.com) -''' +""" import collections diff --git a/codes/python/include/linked_list.py b/codes/python/include/linked_list.py index f6773c6f2..e2eff9a2c 100644 --- a/codes/python/include/linked_list.py +++ b/codes/python/include/linked_list.py @@ -1,8 +1,8 @@ -''' +""" File: linked_list.py Created Time: 2021-12-11 Author: Krahets (krahets@163.com) -''' +""" class ListNode: """Definition for a singly-linked list node diff --git a/codes/python/include/print_util.py b/codes/python/include/print_util.py index f84d548b4..9f211806c 100644 --- a/codes/python/include/print_util.py +++ b/codes/python/include/print_util.py @@ -1,8 +1,8 @@ -''' +""" File: print_util.py Created Time: 2021-12-11 Author: Krahets (krahets@163.com), msk397 (machangxinq@gmail.com) -''' +""" import copy import queue diff --git a/docs/chapter_computational_complexity/time_complexity.md b/docs/chapter_computational_complexity/time_complexity.md index a482c7ae1..0313c533b 100644 --- a/docs/chapter_computational_complexity/time_complexity.md +++ b/docs/chapter_computational_complexity/time_complexity.md @@ -325,7 +325,7 @@ $T(n)$ 是个一次函数,说明时间增长趋势是线性的,因此易得 $$ T(n) \leq c \cdot f(n) $$ - 则可认为 $f(n)$ 给出了 $T(n)$ 的一个渐近上界,记为 + 则可认为 $f(n)$ 给出了 $T(n)$ 的一个渐近上界,记为 $$ T(n) = O(f(n)) $$ diff --git a/docs/chapter_data_structure/data_and_memory.md b/docs/chapter_data_structure/data_and_memory.md index 930f37622..4fc32f056 100644 --- a/docs/chapter_data_structure/data_and_memory.md +++ b/docs/chapter_data_structure/data_and_memory.md @@ -10,10 +10,10 @@ comments: true **「基本数据类型」是 CPU 可以直接进行运算的类型,在算法中直接被使用。** -- 「整数」根据不同的长度分为 byte, short, int, long ,根据算法需求选用,即在满足取值范围的情况下尽量减小内存空间占用。 -- 「浮点数」代表小数,根据长度分为 float, double ,同样根据算法的实际需求选用。 -- 「字符」在计算机中是以字符集的形式保存的,char 的值实际上是数字,代表字符集中的编号,计算机通过字符集查表来完成编号到字符的转换。 -- 「布尔」代表逻辑中的 ”是“ 与 ”否“ ,其占用空间需要具体根据编程语言确定,通常为 1 byte 或 1 bit 。 +- 「整数」根据不同的长度分为 byte, short, int, long ,根据算法需求选用,即在满足取值范围的情况下尽量减小内存空间占用; +- 「浮点数」代表小数,根据长度分为 float, double ,同样根据算法的实际需求选用; +- 「字符」在计算机中是以字符集的形式保存的,char 的值实际上是数字,代表字符集中的编号,计算机通过字符集查表来完成编号到字符的转换。占用空间与具体编程语言有关,通常为 2 bytes 或 1 byte ; +- 「布尔」代表逻辑中的 ”是“ 与 ”否“ ,其占用空间需要具体根据编程语言确定,通常为 1 byte 或 1 bit ; !!! note "字节与比特" @@ -31,7 +31,7 @@ comments: true | | long | 8 bytes | $-2^{63}$ ~ $2^{63} - 1$ | $0$ | | 浮点数 | **float** | 4 bytes | $-3.4 \times 10^{38}$ ~ $3.4 \times 10^{38}$ | $0.0$ f | | | double | 8 bytes | $-1.7 \times 10^{308}$ ~ $1.7 \times 10^{308}$ | $0.0$ | -| 字符 | **char** | 2 bytes | $0$ ~ $2^{16} - 1$ | $0$ | +| 字符 | **char** | 2 bytes / 1 byte | $0$ ~ $2^{16} - 1$ | $0$ | | 布尔 | **boolean(bool)** | 1 byte / 1 bit | $\text{true}$ 或 $\text{false}$ | $\text{false}$ | @@ -63,7 +63,8 @@ comments: true === "Python" ```python title="" - + """ Python 的 list 可以自由存储各种基本数据类型和对象 """ + list = [0, 0.0, 'a', False] ``` === "Go" @@ -93,7 +94,11 @@ comments: true === "C#" ```csharp title="" - + /* 使用多种「基本数据类型」来初始化「数组」 */ + int[] numbers = new int[5]; + float[] decimals = new float[5]; + char[] characters = new char[5]; + bool[] booleans = new bool[5]; ``` ## 计算机内存 diff --git a/docs/chapter_introduction/what_is_dsa.md b/docs/chapter_introduction/what_is_dsa.md index 12ba333b1..67b3c37e1 100644 --- a/docs/chapter_introduction/what_is_dsa.md +++ b/docs/chapter_introduction/what_is_dsa.md @@ -31,12 +31,23 @@ comments: true - 算法是发挥数据结构优势的舞台。数据结构仅存储数据信息,结合算法才可解决特定问题。 - 算法有对应最优的数据结构。给定算法,一般可基于不同的数据结构实现,而最终执行效率往往相差很大。 -如果将数据结构与算法比作「LEGO 乐高」,数据结构就是乐高「积木」,而算法就是把积木拼成目标形态的一系列「操作步骤」。 - ![relationship_between_data_structure_and_algorithm](what_is_dsa.assets/relationship_between_data_structure_and_algorithm.png)

Fig. 数据结构与算法的关系

+如果将「LEGO 乐高」类比到「数据结构与算法」,那么可以得到下表所示的对应关系。 + +
+ +| 数据结构与算法 | LEGO 乐高 | +| -------------- | ---------------------------------------- | +| 输入数据 | 未拼装的积木 | +| 数据结构 | 积木组织形式,包括形状、大小、连接方式等 | +| 算法 | 把积木拼成目标形态的一系列操作步骤 | +| 输出数据 | 积木模型 | + +
+ !!! tip "约定俗成的简称" 在实际讨论中,我们通常会将「数据结构与算法」直接简称为「算法」。例如,我们熟称的 LeetCode 算法题目,实际上同时考察了数据结构和算法两部分知识。 diff --git a/docs/chapter_searching/binary_search.md b/docs/chapter_searching/binary_search.md index dd9192e09..7e765a67f 100644 --- a/docs/chapter_searching/binary_search.md +++ b/docs/chapter_searching/binary_search.md @@ -29,31 +29,24 @@ $$ 首先,我们先采用“双闭区间”的表示,在数组 `nums` 中查找目标元素 `target` 的对应索引。 === "Step 1" - ![binary_search_step1](binary_search.assets/binary_search_step1.png) === "Step 2" - ![binary_search_step2](binary_search.assets/binary_search_step2.png) === "Step 3" - ![binary_search_step3](binary_search.assets/binary_search_step3.png) === "Step 4" - ![binary_search_step4](binary_search.assets/binary_search_step4.png) === "Step 5" - ![binary_search_step5](binary_search.assets/binary_search_step5.png) === "Step 6" - ![binary_search_step6](binary_search.assets/binary_search_step6.png) === "Step 7" - ![binary_search_step7](binary_search.assets/binary_search_step7.png) 二分查找“双闭区间”表示下的代码如下所示。 @@ -146,7 +139,23 @@ $$ === "JavaScript" ```js 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; + } ``` === "TypeScript" @@ -260,7 +269,23 @@ $$ === "JavaScript" ```js 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; + } ``` === "TypeScript" @@ -337,7 +362,10 @@ $$ === "JavaScript" ```js title="" - + // (i + j) 有可能超出 int 的取值范围 + let m = parseInt((i + j) / 2); + // 更换为此写法则不会越界 + let m = parseInt(i + (j - i) / 2); ``` === "TypeScript" diff --git a/docs/chapter_searching/linear_search.md b/docs/chapter_searching/linear_search.md index 8822d375c..e1a4ac142 100644 --- a/docs/chapter_searching/linear_search.md +++ b/docs/chapter_searching/linear_search.md @@ -76,6 +76,18 @@ comments: true === "JavaScript" ```js 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; + } ``` @@ -167,7 +179,19 @@ comments: true === "JavaScript" ```js title="linear_search.js" - + /* 线性查找(链表)*/ + function linearSearchLinkedList(head, target) { + // 遍历链表 + while(head) { + // 找到目标结点,返回之 + if(head.val === target) { + return head; + } + head = head.next; + } + // 未找到目标结点,返回 null + return null; + } ``` === "TypeScript" diff --git a/docs/chapter_tree/binary_tree.assets/array_representation_complete_binary_tree.png b/docs/chapter_tree/binary_tree.assets/array_representation_complete_binary_tree.png new file mode 100644 index 000000000..f369d5d58 Binary files /dev/null and b/docs/chapter_tree/binary_tree.assets/array_representation_complete_binary_tree.png differ diff --git a/docs/chapter_tree/binary_tree.assets/array_representation_mapping.png b/docs/chapter_tree/binary_tree.assets/array_representation_mapping.png new file mode 100644 index 000000000..5c51843bc Binary files /dev/null and b/docs/chapter_tree/binary_tree.assets/array_representation_mapping.png differ diff --git a/docs/chapter_tree/binary_tree.assets/array_representation_with_empty.png b/docs/chapter_tree/binary_tree.assets/array_representation_with_empty.png new file mode 100644 index 000000000..7d1be8dd1 Binary files /dev/null and b/docs/chapter_tree/binary_tree.assets/array_representation_with_empty.png differ diff --git a/docs/chapter_tree/binary_tree.assets/array_representation_without_empty.png b/docs/chapter_tree/binary_tree.assets/array_representation_without_empty.png new file mode 100644 index 000000000..d0f5d9bc1 Binary files /dev/null and b/docs/chapter_tree/binary_tree.assets/array_representation_without_empty.png differ diff --git a/docs/chapter_tree/binary_tree.md b/docs/chapter_tree/binary_tree.md index f5e3b7b9d..ed4582904 100644 --- a/docs/chapter_tree/binary_tree.md +++ b/docs/chapter_tree/binary_tree.md @@ -377,3 +377,82 @@ comments: true | 树的结点总数为 $n$ 时的高度 | $\log_2 (n+1) - 1$ | $n - 1$ | + +## 二叉树表示方式 * + +我们一般使用二叉树的「链表表示」,即存储单位为结点 `TreeNode` ,结点之间通过指针(引用)相连接。本文前述示例代码展示了二叉树在链表表示下的各项基本操作。 + +那能否可以用「数组表示」二叉树呢?答案是肯定的。先来分析一个简单案例,给定一个「完美二叉树」,将结点按照层序遍历的顺序编号(从 0 开始),那么可以推导得出父结点索引与子结点索引之间的「映射公式」:**设结点的索引为 $i$ ,则该结点的左子结点索引为 $2i + 1$ 、右子结点索引为 $2i + 2$** 。 + +**本质上,映射公式的作用就是链表中的指针**。对于层序遍历序列中的任意结点,我们都可以使用映射公式来访问子结点。因此,可以直接使用层序遍历序列(即数组)来表示完美二叉树。 + +![array_representation_mapping](binary_tree.assets/array_representation_mapping.png) + +然而,完美二叉树只是个例,二叉树中间层往往存在许多空结点(即 `null` ),而层序遍历序列并不包含这些空结点,并且我们无法单凭序列来猜测空结点的数量和分布位置,**即理论上存在许多种二叉树都符合该层序遍历序列**。显然,这种情况无法使用数组来存储二叉树。 + +![array_representation_without_empty](binary_tree.assets/array_representation_without_empty.png) + +为了解决此问题,考虑按照完美二叉树的形式来表示所有二叉树,**即在序列中使用特殊符号来显式地表示“空位”**。如下图所示,这样处理后,序列(数组)就可以唯一表示二叉树了。 + +=== "Java" + + ```java title="" + /* 二叉树的数组表示 */ + // 使用 int 的包装类 Integer ,就可以使用 null 来标记空位 + Integer[] tree = { 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 }; + ``` + +=== "C++" + + ```cpp title="" + /* 二叉树的数组表示 */ + // 为了符合数据类型为 int ,使用 int 最大值标记空位 + // 该方法的使用前提是没有结点的值 = INT_MAX + vector tree = { 1, 2, 3, 4, INT_MAX, 6, 7, 8, 9, INT_MAX, INT_MAX, 12, INT_MAX, INT_MAX, 15 }; + ``` + +=== "Python" + + ```python title="" + “”“ 二叉树的数组表示 ”“” + # 直接使用 None 来表示空位 + tree = [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15] + ``` + +=== "Go" + + ```go title="" + + ``` + +=== "JavaScript" + + ```js title="" + + ``` + +=== "TypeScript" + + ```typescript title="" + + ``` + +=== "C" + + ```c title="" + + ``` + +=== "C#" + + ```csharp title="" + + ``` + +![array_representation_with_empty](binary_tree.assets/array_representation_with_empty.png) + +回顾「完全二叉树」的满足条件,其只有最底层有空结点,并且最底层的结点尽量靠左,因而所有空结点都一定出现在层序遍历序列的末尾。**因为我们先验地确定了空位的位置,所以在使用数组表示完全二叉树时,可以省略存储“空位”**。“便于使用数组表示”也是完全二叉树受欢迎的原因之一。 + +![array_representation_complete_binary_tree](binary_tree.assets/array_representation_complete_binary_tree.png) + +数组表示有两个优点: 一是不需要存储指针,节省空间;二是可以随机访问结点。然而,当二叉树中的“空位”很多时,数组中只包含很少结点的数据,空间利用率很低。 diff --git a/docs/index.md b/docs/index.md index b0a533086..71c34360d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,12 +51,12 @@ hide: !!! quote "" -

“追风赶月莫停留,平芜尽处是春山“

+

“追风赶月莫停留,平芜尽处是春山”

一起加油!

--- -## 推荐语 +

推荐语

!!! quote @@ -64,7 +64,7 @@ hide: **—— 邓俊辉,清华大学计算机系教授** -## 致谢 +

致谢

感谢本开源书的每一位撰稿人,是他们的无私奉献让这本书变得更好,他们是: