Prepare 1.0.0 release (#1044)

* Update the book with the thrid revised edition

* Fix a typo

* Update the contributors' information

* Update the mindmap

* Update the version number
pull/1052/head 1.0.0
Yudong Jin 10 months ago committed by GitHub
parent b9ae4ffe9a
commit f6976978dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,7 +8,7 @@
#define MAX_SIZE 100 #define MAX_SIZE 100
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
void backtrack(int row, int n, char state[MAX_SIZE][MAX_SIZE], char ***res, int *resSize, bool cols[MAX_SIZE], void backtrack(int row, int n, char state[MAX_SIZE][MAX_SIZE], char ***res, int *resSize, bool cols[MAX_SIZE],
bool diags1[2 * MAX_SIZE - 1], bool diags2[2 * MAX_SIZE - 1]) { bool diags1[2 * MAX_SIZE - 1], bool diags2[2 * MAX_SIZE - 1]) {
// 当放置完所有行时,记录解 // 当放置完所有行时,记录解
@ -40,7 +40,7 @@ void backtrack(int row, int n, char state[MAX_SIZE][MAX_SIZE], char ***res, int
} }
} }
/* 求解 N 皇后 */ /* 求解 n 皇后 */
char ***nQueens(int n, int *returnSize) { char ***nQueens(int n, int *returnSize) {
char state[MAX_SIZE][MAX_SIZE]; char state[MAX_SIZE][MAX_SIZE];
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位

@ -6,7 +6,7 @@
#include "../utils/common.hpp" #include "../utils/common.hpp"
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
void backtrack(int row, int n, vector<vector<string>> &state, vector<vector<vector<string>>> &res, vector<bool> &cols, void backtrack(int row, int n, vector<vector<string>> &state, vector<vector<vector<string>>> &res, vector<bool> &cols,
vector<bool> &diags1, vector<bool> &diags2) { vector<bool> &diags1, vector<bool> &diags2) {
// 当放置完所有行时,记录解 // 当放置完所有行时,记录解
@ -33,7 +33,7 @@ void backtrack(int row, int n, vector<vector<string>> &state, vector<vector<vect
} }
} }
/* 求解 N 皇后 */ /* 求解 n 皇后 */
vector<vector<vector<string>>> nQueens(int n) { vector<vector<vector<string>>> nQueens(int n) {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
vector<vector<string>> state(n, vector<string>(n, "#")); vector<vector<string>> state(n, vector<string>(n, "#"));

@ -7,7 +7,7 @@
namespace hello_algo.chapter_backtracking; namespace hello_algo.chapter_backtracking;
public class n_queens { public class n_queens {
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
void Backtrack(int row, int n, List<List<string>> state, List<List<List<string>>> res, void Backtrack(int row, int n, List<List<string>> state, List<List<List<string>>> res,
bool[] cols, bool[] diags1, bool[] diags2) { bool[] cols, bool[] diags1, bool[] diags2) {
// 当放置完所有行时,记录解 // 当放置完所有行时,记录解
@ -38,7 +38,7 @@ public class n_queens {
} }
} }
/* 求解 N 皇后 */ /* 求解 n 皇后 */
List<List<List<string>>> NQueens(int n) { List<List<List<string>>> NQueens(int n) {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
List<List<string>> state = []; List<List<string>> state = [];

@ -4,7 +4,7 @@
* Author: liuyuxin (gvenusleo@gmail.com) * Author: liuyuxin (gvenusleo@gmail.com)
*/ */
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
void backtrack( void backtrack(
int row, int row,
int n, int n,
@ -46,7 +46,7 @@ void backtrack(
} }
} }
/* 求解 N 皇后 */ /* 求解 n 皇后 */
List<List<List<String>>> nQueens(int n) { List<List<List<String>>> nQueens(int n) {
// n*n 'Q' '#' // n*n 'Q' '#'
List<List<String>> state = List.generate(n, (index) => List.filled(n, "#")); List<List<String>> state = List.generate(n, (index) => List.filled(n, "#"));

@ -4,7 +4,7 @@
package chapter_backtracking package chapter_backtracking
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
func backtrack(row, n int, state *[][]string, res *[][][]string, cols, diags1, diags2 *[]bool) { func backtrack(row, n int, state *[][]string, res *[][][]string, cols, diags1, diags2 *[]bool) {
// 当放置完所有行时,记录解 // 当放置完所有行时,记录解
if row == n { if row == n {
@ -35,6 +35,7 @@ func backtrack(row, n int, state *[][]string, res *[][][]string, cols, diags1, d
} }
} }
/* 求解 n 皇后 */
func nQueens(n int) [][][]string { func nQueens(n int) [][][]string {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
state := make([][]string, n) state := make([][]string, n)

@ -9,7 +9,7 @@ package chapter_backtracking;
import java.util.*; import java.util.*;
public class n_queens { public class n_queens {
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
public static void backtrack(int row, int n, List<List<String>> state, List<List<List<String>>> res, public static void backtrack(int row, int n, List<List<String>> state, List<List<List<String>>> res,
boolean[] cols, boolean[] diags1, boolean[] diags2) { boolean[] cols, boolean[] diags1, boolean[] diags2) {
// 当放置完所有行时,记录解 // 当放置完所有行时,记录解
@ -40,7 +40,7 @@ public class n_queens {
} }
} }
/* 求解 N 皇后 */ /* 求解 n 皇后 */
public static List<List<List<String>>> nQueens(int n) { public static List<List<List<String>>> nQueens(int n) {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
List<List<String>> state = new ArrayList<>(); List<List<String>> state = new ArrayList<>();

@ -4,7 +4,7 @@
* Author: Justin (xiefahit@gmail.com) * Author: Justin (xiefahit@gmail.com)
*/ */
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
function backtrack(row, n, state, res, cols, diags1, diags2) { function backtrack(row, n, state, res, cols, diags1, diags2) {
// 当放置完所有行时,记录解 // 当放置完所有行时,记录解
if (row === n) { if (row === n) {
@ -30,7 +30,7 @@ function backtrack(row, n, state, res, cols, diags1, diags2) {
} }
} }
/* 求解 N 皇后 */ /* 求解 n 皇后 */
function nQueens(n) { function nQueens(n) {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
const state = Array.from({ length: n }, () => Array(n).fill('#')); const state = Array.from({ length: n }, () => Array(n).fill('#'));

@ -14,7 +14,7 @@ def backtrack(
diags1: list[bool], diags1: list[bool],
diags2: list[bool], diags2: list[bool],
): ):
"""回溯算法:N 皇后""" """回溯算法:n 皇后"""
# 当放置完所有行时,记录解 # 当放置完所有行时,记录解
if row == n: if row == n:
res.append([list(row) for row in state]) res.append([list(row) for row in state])
@ -37,7 +37,7 @@ def backtrack(
def n_queens(n: int) -> list[list[list[str]]]: def n_queens(n: int) -> list[list[list[str]]]:
"""求解 N 皇后""" """求解 n 皇后"""
# 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 # 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
state = [["#" for _ in range(n)] for _ in range(n)] state = [["#" for _ in range(n)] for _ in range(n)]
cols = [False] * n # 记录列是否有皇后 cols = [False] * n # 记录列是否有皇后

@ -4,7 +4,7 @@
* Author: codingonion (coderonion@gmail.com) * Author: codingonion (coderonion@gmail.com)
*/ */
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
fn backtrack(row: usize, n: usize, state: &mut Vec<Vec<String>>, res: &mut Vec<Vec<Vec<String>>>, fn backtrack(row: usize, n: usize, state: &mut Vec<Vec<String>>, res: &mut Vec<Vec<Vec<String>>>,
cols: &mut [bool], diags1: &mut [bool], diags2: &mut [bool]) { cols: &mut [bool], diags1: &mut [bool], diags2: &mut [bool]) {
// 当放置完所有行时,记录解 // 当放置完所有行时,记录解
@ -35,7 +35,7 @@ fn backtrack(row: usize, n: usize, state: &mut Vec<Vec<String>>, res: &mut Vec<V
} }
} }
/* 求解 N 皇后 */ /* 求解 n 皇后 */
fn n_queens(n: usize) -> Vec<Vec<Vec<String>>> { fn n_queens(n: usize) -> Vec<Vec<Vec<String>>> {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
let mut state: Vec<Vec<String>> = Vec::new(); let mut state: Vec<Vec<String>> = Vec::new();

@ -4,7 +4,7 @@
* Author: nuomi1 (nuomi1@qq.com) * Author: nuomi1 (nuomi1@qq.com)
*/ */
/* N */ /* n */
func backtrack(row: Int, n: Int, state: inout [[String]], res: inout [[[String]]], cols: inout [Bool], diags1: inout [Bool], diags2: inout [Bool]) { func backtrack(row: Int, n: Int, state: inout [[String]], res: inout [[[String]]], cols: inout [Bool], diags1: inout [Bool], diags2: inout [Bool]) {
// //
if row == n { if row == n {
@ -34,7 +34,7 @@ func backtrack(row: Int, n: Int, state: inout [[String]], res: inout [[[String]]
} }
} }
/* N */ /* n */
func nQueens(n: Int) -> [[[String]]] { func nQueens(n: Int) -> [[[String]]] {
// n*n 'Q' '#' // n*n 'Q' '#'
var state = Array(repeating: Array(repeating: "#", count: n), count: n) var state = Array(repeating: Array(repeating: "#", count: n), count: n)

@ -4,7 +4,7 @@
* Author: Justin (xiefahit@gmail.com) * Author: Justin (xiefahit@gmail.com)
*/ */
/* 回溯算法:N 皇后 */ /* 回溯算法:n 皇后 */
function backtrack( function backtrack(
row: number, row: number,
n: number, n: number,
@ -38,7 +38,7 @@ function backtrack(
} }
} }
/* 求解 N 皇后 */ /* 求解 n 皇后 */
function nQueens(n: number): string[][][] { function nQueens(n: number): string[][][] {
// 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位
const state = Array.from({ length: n }, () => Array(n).fill('#')); const state = Array.from({ length: n }, () => Array(n).fill('#'));

@ -30,7 +30,7 @@ The main content of the book is shown in the following figure.
## Acknowledgements ## Acknowledgements
This book is continuously improved with the joint efforts of many contributors from the open-source community. Thanks to each writer who invested their time and energy, listed in the order generated by GitHub: krahets、codingonion、nuomi1、Gonglja、Reanon、justin-tse、danielsss、hpstory、S-N-O-R-L-A-X、night-cruise、msk397、gvenusleo、RiverTwilight、gyt95、zhuoqinyue、Zuoxun、Xia-Sang、mingXta、FangYuan33、GN-Yu、IsChristina、xBLACKICEx、guowei-gong、Cathay-Chen、mgisr、JoseHung、qualifier1024、pengchzn、Guanngxu、longsizhuo、L-Super、what-is-me、yuan0221、lhxsm、Slone123c、WSL0809、longranger2、theNefelibatas、xiongsp、JeffersonHuang、hongyun-robot、K3v123、yuelinxin、a16su、gaofer、malone6、Wonderdch、xjr7670、DullSword、Horbin-Magician、NI-SW、reeswell、XC-Zero、XiaChuerwu、yd-j、iron-irax、huawuque404、MolDuM、Nigh、KorsChen、foursevenlove、52coder、bubble9um、youshaoXG、curly210102、gltianwen、fanchenggang、Transmigration-zhou、FloranceYeh、FreddieLi、ShiMaRing、lipusheng、Javesun99、JackYang-hellobobo、shanghai-Jerry、0130w、Keynman、psychelzh、logan-qiu、ZnYang2018、MwumLi、1ch0、Phoenix0415、qingpeng9802、Richard-Zhang1019、QiLOL、Suremotoo、Turing-1024-Lee、Evilrabbit520、GaochaoZhu、ZJKung、linzeyan、hezhizhen、ZongYangL、beintentional、czruby、coderlef、dshlstarr、szu17dmy、fbigm、gledfish、hts0000、boloboloda、iStig、jiaxianhua、wenjianmin、keshida、kilikilikid、lclc6、lwbaptx、liuxjerry、lucaswangdev、lyl625760、chadyi、noobcodemaker、selear、siqyka、syd168、4yDX3906、tao363、wangwang105、weibk、yabo083、yi427、yishangzhang、zhouLion、baagod、ElaBosak233、xb534、luluxia、yanedie、thomasq0 和 YangXuanyi。 This book is continuously improved with the joint efforts of many contributors from the open-source community. Thanks to each writer who invested their time and energy, listed in the order generated by GitHub: krahets, codingonion, nuomi1, Gonglja, Reanon, justin-tse, danielsss, hpstory, S-N-O-R-L-A-X, night-cruise, msk397, gvenusleo, RiverTwilight, gyt95, zhuoqinyue, Zuoxun, Xia-Sang, mingXta, FangYuan33, GN-Yu, IsChristina, xBLACKICEx, guowei-gong, Cathay-Chen, mgisr, JoseHung, qualifier1024, pengchzn, Guanngxu, longsizhuo, L-Super, what-is-me, yuan0221, lhxsm, Slone123c, WSL0809, longranger2, theNefelibatas, xiongsp, JeffersonHuang, hongyun-robot, K3v123, yuelinxin, a16su, gaofer, malone6, Wonderdch, xjr7670, DullSword, Horbin-Magician, NI-SW, reeswell, XC-Zero, XiaChuerwu, yd-j, iron-irax, huawuque404, MolDuM, Nigh, KorsChen, foursevenlove, 52coder, bubble9um, youshaoXG, curly210102, gltianwen, fanchenggang, Transmigration-zhou, FloranceYeh, FreddieLi, ShiMaRing, lipusheng, Javesun99, JackYang-hellobobo, shanghai-Jerry, 0130w, Keynman, psychelzh, logan-qiu, ZnYang2018, MwumLi, 1ch0, Phoenix0415, qingpeng9802, Richard-Zhang1019, QiLOL, Suremotoo, Turing-1024-Lee, Evilrabbit520, GaochaoZhu, ZJKung, linzeyan, hezhizhen, ZongYangL, beintentional, czruby, coderlef, dshlstarr, szu17dmy, fbigm, gledfish, hts0000, boloboloda, iStig, jiaxianhua, wenjianmin, keshida, kilikilikid, lclc6, lwbaptx, liuxjerry, lucaswangdev, lyl625760, chadyi, noobcodemaker, selear, siqyka, syd168, 4yDX3906, tao363, wangwang105, weibk, yabo083, yi427, yishangzhang, zhouLion, baagod, ElaBosak233, xb534, luluxia, yanedie, thomasq0, YangXuanyi and th1nk3r-ing.
The code review work for this book was completed by codingonion, Gonglja, gvenusleo, hpstory, justintse, krahets, night-cruise, nuomi1, and Reanon (listed in alphabetical order). Thanks to them for their time and effort, ensuring the standardization and uniformity of the code in various languages. The code review work for this book was completed by codingonion, Gonglja, gvenusleo, hpstory, justintse, krahets, night-cruise, nuomi1, and Reanon (listed in alphabetical order). Thanks to them for their time and effort, ensuring the standardization and uniformity of the code in various languages.

@ -53,7 +53,7 @@
| 根节点 | root node | 剪枝 | pruning | | 根节点 | root node | 剪枝 | pruning |
| 叶节点 | leaf node | 全排列问题 | permutations problem | | 叶节点 | leaf node | 全排列问题 | permutations problem |
| 边 | edge | 子集和问题 | subset-sum problem | | 边 | edge | 子集和问题 | subset-sum problem |
| 层 | level | N 皇后问题 | N-queens problem | | 层 | level | n 皇后问题 | n-queens problem |
| 度 | degree | 动态规划 | dynamic programming | | 度 | degree | 动态规划 | dynamic programming |
| 高度 | height | 初始状态 | initial state | | 高度 | height | 初始状态 | initial state |
| 深度 | depth | 状态转移方程 | state-trasition equation | | 深度 | depth | 状态转移方程 | state-trasition equation |

@ -5,8 +5,8 @@
- 数组和链表是两种基本的数据结构,分别代表数据在计算机内存中的两种存储方式:连续空间存储和分散空间存储。两者的特点呈现出互补的特性。 - 数组和链表是两种基本的数据结构,分别代表数据在计算机内存中的两种存储方式:连续空间存储和分散空间存储。两者的特点呈现出互补的特性。
- 数组支持随机访问、占用内存较少;但插入和删除元素效率低,且初始化后长度不可变。 - 数组支持随机访问、占用内存较少;但插入和删除元素效率低,且初始化后长度不可变。
- 链表通过更改引用(指针)实现高效的节点插入与删除,且可以灵活调整长度;但节点访问效率低、占用内存较多。常见的链表类型包括单向链表、环形链表、双向链表。 - 链表通过更改引用(指针)实现高效的节点插入与删除,且可以灵活调整长度;但节点访问效率低、占用内存较多。常见的链表类型包括单向链表、环形链表、双向链表。
- 列表是一种支持增删查改的元素有序集合,通常基于动态数组实现它保留了数组的优势,同时可以灵活调整长度。 - 列表是一种支持增删查改的元素有序集合,通常基于动态数组实现它保留了数组的优势,同时可以灵活调整长度。
- 列表的出现大幅提高了数组的实用性,但可能导致部分内存空间浪费。 - 列表的出现大幅提高了数组的实用性,但可能导致部分内存空间浪费。
- 程序运行时,数据主要存储在内存中。数组可提供更高的内存空间效率,而链表则在内存使用上更加灵活。 - 程序运行时,数据主要存储在内存中。数组可提供更高的内存空间效率,而链表则在内存使用上更加灵活。
- 缓存通过缓存行、预取机制以及空间局部性和时间局部性等数据加载机制,为 CPU 提供快速数据访问,显著提升程序的执行效率。 - 缓存通过缓存行、预取机制以及空间局部性和时间局部性等数据加载机制,为 CPU 提供快速数据访问,显著提升程序的执行效率。
- 由于数组具有更高的缓存命中率,因此它通常比链表更高效。在选择数据结构时,应根据具体需求和场景做出恰当选择。 - 由于数组具有更高的缓存命中率,因此它通常比链表更高效。在选择数据结构时,应根据具体需求和场景做出恰当选择。
@ -21,14 +21,14 @@
2. 大小限制:栈内存相对较小,堆的大小一般受限于可用内存。因此堆更加适合存储大型数组。 2. 大小限制:栈内存相对较小,堆的大小一般受限于可用内存。因此堆更加适合存储大型数组。
3. 灵活性:栈上的数组的大小需要在编译时确定,而堆上的数组的大小可以在运行时动态确定。 3. 灵活性:栈上的数组的大小需要在编译时确定,而堆上的数组的大小可以在运行时动态确定。
**Q**:为什么数组要求相同类型的元素,而在链表中却没有强调同类型呢? **Q**:为什么数组要求相同类型的元素,而在链表中却没有强调同类型呢?
链表由节点组成,节点之间通过引用(指针)连接,各个节点可以存储不同类型的数据,例如 `int`、`double`、`string`、`object` 等。 链表由节点组成,节点之间通过引用(指针)连接,各个节点可以存储不同类型的数据,例如 `int`、`double`、`string`、`object` 等。
相对地,数组元素则必须是相同类型的,这样才能通过计算偏移量来获取对应元素位置。例如,数组同时包含 `int``long` 两种类型,单个元素分别占用 4 字节 和 8 字节 ,此时就不能用以下公式计算偏移量了,因为数组中包含了两种“元素长度”。 相对地,数组元素则必须是相同类型的,这样才能通过计算偏移量来获取对应元素位置。例如,数组同时包含 `int``long` 两种类型,单个元素分别占用 4 字节 和 8 字节 ,此时就不能用以下公式计算偏移量了,因为数组中包含了两种“元素长度”。
```shell ```shell
# 元素内存地址 = 数组内存地址 + 元素长度 * 元素索引 # 元素内存地址 = 数组内存地址(首元素内存地址) + 元素长度 * 元素索引
``` ```
**Q**:删除节点后,是否需要把 `P.next` 设为 `None` 呢? **Q**:删除节点后,是否需要把 `P.next` 设为 `None` 呢?

@ -1,4 +1,4 @@
# N 皇后问题 # n 皇后问题
!!! question !!! question

@ -10,7 +10,7 @@
- **时间效率**:算法运行速度的快慢。 - **时间效率**:算法运行速度的快慢。
- **空间效率**:算法占用内存空间的大小。 - **空间效率**:算法占用内存空间的大小。
简而言之,**我们的目标是设计“既快又省”的数据结构与算法**。而有效地评估算法效率至关重要,因为只有这样我们才能将各种算法进行对比,进而指导算法设计与优化过程。 简而言之,**我们的目标是设计“既快又省”的数据结构与算法**。而有效地评估算法效率至关重要,因为只有这样我们才能将各种算法进行对比,进而指导算法设计与优化过程。
效率评估方法主要分为两种:实际测试、理论估算。 效率评估方法主要分为两种:实际测试、理论估算。

@ -90,7 +90,7 @@ $$
细心的你可能会发现:`int` 和 `float` 长度相同,都是 4 字节 ,但为什么 `float` 的取值范围远大于 `int` ?这非常反直觉,因为按理说 `float` 需要表示小数,取值范围应该变小才对。 细心的你可能会发现:`int` 和 `float` 长度相同,都是 4 字节 ,但为什么 `float` 的取值范围远大于 `int` ?这非常反直觉,因为按理说 `float` 需要表示小数,取值范围应该变小才对。
实际上,**这是因为浮点数 `float` 采用了不同的表示方式**。记一个 32 长度的二进制数为: 实际上,**这是因为浮点数 `float` 采用了不同的表示方式**。记一个 32 比特长度的二进制数为:
$$ $$
b_{31} b_{30} b_{29} \ldots b_2 b_1 b_0 b_{31} b_{30} b_{29} \ldots b_2 b_1 b_0
@ -133,7 +133,7 @@ $$
现在我们可以回答最初的问题:**`float` 的表示方式包含指数位,导致其取值范围远大于 `int`** 。根据以上计算,`float` 可表示的最大正数为 $2^{254 - 127} \times (2 - 2^{-23}) \approx 3.4 \times 10^{38}$ ,切换符号位便可得到最小负数。 现在我们可以回答最初的问题:**`float` 的表示方式包含指数位,导致其取值范围远大于 `int`** 。根据以上计算,`float` 可表示的最大正数为 $2^{254 - 127} \times (2 - 2^{-23}) \approx 3.4 \times 10^{38}$ ,切换符号位便可得到最小负数。
**尽管浮点数 `float` 扩展了取值范围,但其副作用是牺牲了精度**。整数类型 `int` 将全部 32 用于表示数字,数字是均匀分布的;而由于指数位的存在,浮点数 `float` 的数值越大,相邻两个数字之间的差值就会趋向越大。 **尽管浮点数 `float` 扩展了取值范围,但其副作用是牺牲了精度**。整数类型 `int` 将全部 32 比特用于表示数字,数字是均匀分布的;而由于指数位的存在,浮点数 `float` 的数值越大,相邻两个数字之间的差值就会趋向越大。
如下表所示,指数位 $E = 0$ 和 $E = 255$ 具有特殊含义,**用于表示零、无穷大、$\mathrm{NaN}$ 等**。 如下表所示,指数位 $E = 0$ 和 $E = 255$ 具有特殊含义,**用于表示零、无穷大、$\mathrm{NaN}$ 等**。

@ -6,7 +6,7 @@
- 常见的逻辑结构包括线性、树状和网状等。通常我们根据逻辑结构将数据结构分为线性(数组、链表、栈、队列)和非线性(树、图、堆)两种。哈希表的实现可能同时包含线性数据结构和非线性数据结构。 - 常见的逻辑结构包括线性、树状和网状等。通常我们根据逻辑结构将数据结构分为线性(数组、链表、栈、队列)和非线性(树、图、堆)两种。哈希表的实现可能同时包含线性数据结构和非线性数据结构。
- 当程序运行时,数据被存储在计算机内存中。每个内存空间都拥有对应的内存地址,程序通过这些内存地址访问数据。 - 当程序运行时,数据被存储在计算机内存中。每个内存空间都拥有对应的内存地址,程序通过这些内存地址访问数据。
- 物理结构主要分为连续空间存储(数组)和分散空间存储(链表)。所有数据结构都是由数组、链表或两者的组合实现的。 - 物理结构主要分为连续空间存储(数组)和分散空间存储(链表)。所有数据结构都是由数组、链表或两者的组合实现的。
- 计算机中的基本数据类型包括整数 `byte`、`short`、`int`、`long` ,浮点数 `float`、`double` ,字符 `char` 和布尔 `boolean` 。它们的取值范围取决于占用空间大小和表示方式。 - 计算机中的基本数据类型包括整数 `byte`、`short`、`int`、`long` ,浮点数 `float`、`double` ,字符 `char` 和布尔 `bool` 。它们的取值范围取决于占用空间大小和表示方式。
- 原码、反码和补码是在计算机中编码数字的三种方法,它们之间可以相互转换。整数的原码的最高位是符号位,其余位是数字的值。 - 原码、反码和补码是在计算机中编码数字的三种方法,它们之间可以相互转换。整数的原码的最高位是符号位,其余位是数字的值。
- 整数在计算机中是以补码的形式存储的。在补码表示下,计算机可以对正数和负数的加法一视同仁,不需要为减法操作单独设计特殊的硬件电路,并且不存在正负零歧义的问题。 - 整数在计算机中是以补码的形式存储的。在补码表示下,计算机可以对正数和负数的加法一视同仁,不需要为减法操作单独设计特殊的硬件电路,并且不存在正负零歧义的问题。
- 浮点数的编码由 1 位符号位、8 位指数位和 23 位分数位构成。由于存在指数位,因此浮点数的取值范围远大于整数,代价是牺牲了精度。 - 浮点数的编码由 1 位符号位、8 位指数位和 23 位分数位构成。由于存在指数位,因此浮点数的取值范围远大于整数,代价是牺牲了精度。

@ -2,7 +2,7 @@
!!! question !!! question
给定一棵二叉树的前序遍历 `preorder` 和中序遍历 `inorder` ,请从中构建二叉树,返回二叉树的根节点。假设二叉树中没有值重复的节点,如下图所示 给定一棵二叉树的前序遍历 `preorder` 和中序遍历 `inorder` ,请从中构建二叉树,返回二叉树的根节点。假设二叉树中没有值重复的节点(如下图所示)
![构建二叉树的示例数据](build_binary_tree_problem.assets/build_tree_example.png) ![构建二叉树的示例数据](build_binary_tree_problem.assets/build_tree_example.png)

@ -2,7 +2,7 @@
在本节中,我们先求解另一个常见的背包问题:完全背包,再了解它的一种特例:零钱兑换。 在本节中,我们先求解另一个常见的背包问题:完全背包,再了解它的一种特例:零钱兑换。
## 完全背包 ## 完全背包问题
!!! question !!! question

@ -14,7 +14,7 @@ $$
![链表、树、图之间的关系](graph.assets/linkedlist_tree_graph.png) ![链表、树、图之间的关系](graph.assets/linkedlist_tree_graph.png)
## 图常见类型与术语 ## 图常见类型与术语
根据边是否具有方向,可分为「无向图 undirected graph」和「有向图 directed graph」如下图所示。 根据边是否具有方向,可分为「无向图 undirected graph」和「有向图 directed graph」如下图所示。

@ -1,4 +1,4 @@
# 图基础操作 # 图基础操作
图的基础操作可分为对“边”的操作和对“顶点”的操作。在“邻接矩阵”和“邻接表”两种表示方法下,实现方式有所不同。 图的基础操作可分为对“边”的操作和对“顶点”的操作。在“邻接矩阵”和“邻接表”两种表示方法下,实现方式有所不同。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 162 KiB

@ -30,20 +30,20 @@
## 致谢 ## 致谢
本书在开源社区众多贡献者的共同努力下不断完善。感谢每一位投入时间与精力的撰稿人,他们是(按照 GitHub 自动生成的顺序krahets、codingonion、nuomi1、Gonglja、Reanon、justin-tse、danielsss、hpstory、S-N-O-R-L-A-X、night-cruise、msk397、gvenusleo、RiverTwilight、gyt95、zhuoqinyue、Zuoxun、Xia-Sang、mingXta、FangYuan33、GN-Yu、IsChristina、xBLACKICEx、guowei-gong、Cathay-Chen、mgisr、JoseHung、qualifier1024、pengchzn、Guanngxu、longsizhuo、L-Super、what-is-me、yuan0221、lhxsm、Slone123c、WSL0809、longranger2、theNefelibatas、xiongsp、JeffersonHuang、hongyun-robot、K3v123、yuelinxin、a16su、gaofer、malone6、Wonderdch、xjr7670、DullSword、Horbin-Magician、NI-SW、reeswell、XC-Zero、XiaChuerwu、yd-j、iron-irax、huawuque404、MolDuM、Nigh、KorsChen、foursevenlove、52coder、bubble9um、youshaoXG、curly210102、gltianwen、fanchenggang、Transmigration-zhou、FloranceYeh、FreddieLi、ShiMaRing、lipusheng、Javesun99、JackYang-hellobobo、shanghai-Jerry、0130w、Keynman、psychelzh、logan-qiu、ZnYang2018、MwumLi、1ch0、Phoenix0415、qingpeng9802、Richard-Zhang1019、QiLOL、Suremotoo、Turing-1024-Lee、Evilrabbit520、GaochaoZhu、ZJKung、linzeyan、hezhizhen、ZongYangL、beintentional、czruby、coderlef、dshlstarr、szu17dmy、fbigm、gledfish、hts0000、boloboloda、iStig、jiaxianhua、wenjianmin、keshida、kilikilikid、lclc6、lwbaptx、liuxjerry、lucaswangdev、lyl625760、chadyi、noobcodemaker、selear、siqyka、syd168、4yDX3906、tao363、wangwang105、weibk、yabo083、yi427、yishangzhang、zhouLion、baagod、ElaBosak233、xb534、luluxia、yanedie、thomasq0 和 YangXuanyi 本书在开源社区众多贡献者的共同努力下不断完善。感谢每一位投入时间与精力的撰稿人,他们是(按照 GitHub 自动生成的顺序krahets、codingonion、nuomi1、Gonglja、Reanon、justin-tse、danielsss、hpstory、S-N-O-R-L-A-X、night-cruise、msk397、gvenusleo、RiverTwilight、gyt95、zhuoqinyue、Zuoxun、Xia-Sang、mingXta、FangYuan33、GN-Yu、IsChristina、xBLACKICEx、guowei-gong、Cathay-Chen、mgisr、JoseHung、qualifier1024、pengchzn、Guanngxu、longsizhuo、L-Super、what-is-me、yuan0221、lhxsm、Slone123c、WSL0809、longranger2、theNefelibatas、xiongsp、JeffersonHuang、hongyun-robot、K3v123、yuelinxin、a16su、gaofer、malone6、Wonderdch、xjr7670、DullSword、Horbin-Magician、NI-SW、reeswell、XC-Zero、XiaChuerwu、yd-j、iron-irax、huawuque404、MolDuM、Nigh、KorsChen、foursevenlove、52coder、bubble9um、youshaoXG、curly210102、gltianwen、fanchenggang、Transmigration-zhou、FloranceYeh、FreddieLi、ShiMaRing、lipusheng、Javesun99、JackYang-hellobobo、shanghai-Jerry、0130w、Keynman、psychelzh、logan-qiu、ZnYang2018、MwumLi、1ch0、Phoenix0415、qingpeng9802、Richard-Zhang1019、QiLOL、Suremotoo、Turing-1024-Lee、Evilrabbit520、GaochaoZhu、ZJKung、linzeyan、hezhizhen、ZongYangL、beintentional、czruby、coderlef、dshlstarr、szu17dmy、fbigm、gledfish、hts0000、boloboloda、iStig、jiaxianhua、wenjianmin、keshida、kilikilikid、lclc6、lwbaptx、liuxjerry、lucaswangdev、lyl625760、chadyi、noobcodemaker、selear、siqyka、syd168、4yDX3906、tao363、wangwang105、weibk、yabo083、yi427、yishangzhang、zhouLion、baagod、ElaBosak233、xb534、luluxia、yanedie、thomasq0、YangXuanyi 和 th1nk3r-ing
本书的代码审阅工作由 codingonion, Gonglja、gvenusleo、hpstory、justintse、krahets、night-cruise、nuomi1 和 Reanon 完成(按照首字母顺序排列)。感谢他们付出的时间与精力,正是他们确保了各语言代码的规范与统一。 本书的代码审阅工作由 codingonion、Gonglja、gvenusleo、hpstory、justin-tse、krahets、night-cruise、nuomi1 和 Reanon 完成(按照首字母顺序排列)。感谢他们付出的时间与精力,正是他们确保了各语言代码的规范与统一。
在本书的创作过程中,我得到了许多人的帮助。 在本书的创作过程中,我得到了许多人的帮助。
- 感谢我在公司的导师李汐博士,在一次畅谈中你鼓励我“快行动起来”,坚定了我写这本书的决心; - 感谢我在公司的导师李汐博士,在一次畅谈中你鼓励我“快行动起来”,坚定了我写这本书的决心;
- 感谢我的女朋友泡泡作为本书的首位读者,从算法小白的角度提出许多宝贵建议,使得本书更适合新手阅读; - 感谢我的女朋友泡泡作为本书的首位读者,从算法小白的角度提出许多宝贵建议,使得本书更适合新手阅读;
- 感谢腾宝、琦宝、飞宝为本书起了一个富有创意的名字,唤起大家写下第一行代码 "Hello World!" 的美好回忆; - 感谢腾宝、琦宝、飞宝为本书起了一个富有创意的名字,唤起大家写下第一行代码“Hello World!”的美好回忆;
- 感谢校铨在知识产权方面提供的专业帮助,这对本开源书的完善起到了重要作用; - 感谢校铨在知识产权方面提供的专业帮助,这对本开源书的完善起到了重要作用;
- 感谢苏潼为本书设计了精美的封面和 logo ,并在我的强迫症的驱使下多次耐心修改; - 感谢苏潼为本书设计了精美的封面和 logo ,并在我的强迫症的驱使下多次耐心修改;
- 感谢 @squidfunk 提供的排版建议,以及他开发的开源文档主题 [Material-for-MkDocs](https://github.com/squidfunk/mkdocs-material/tree/master) 。 - 感谢 @squidfunk 提供的排版建议,以及他开发的开源文档主题 [Material-for-MkDocs](https://github.com/squidfunk/mkdocs-material/tree/master) 。
在写作过程中,我阅读了许多关于数据结构与算法的教材和文章。这些作品为本书提供了优秀的范本,确保了本书内容的准确性与品质。在此感谢所有老师和前辈的杰出贡献! 在写作过程中,我阅读了许多关于数据结构与算法的教材和文章。这些作品为本书提供了优秀的范本,确保了本书内容的准确性与品质。在此感谢所有老师和前辈的杰出贡献!
本书倡导手脑并用的学习方式,在这一点上我深受[《动手学深度学习》](https://github.com/d2l-ai/d2l-zh)的启发。在此向各位读者强烈推荐这本优秀的著作。 本书倡导手脑并用的学习方式,在这一点上我深受[《动手学深度学习》](https://github.com/d2l-ai/d2l-zh)的启发。在此向各位读者强烈推荐这本优秀的著作。

@ -171,7 +171,7 @@
相较于文字,视频和图片具有更高的信息密度和结构化程度,更易于理解。在本书中,**重点和难点知识将主要通过动画以图解形式展示**,而文字则作为解释与补充。 相较于文字,视频和图片具有更高的信息密度和结构化程度,更易于理解。在本书中,**重点和难点知识将主要通过动画以图解形式展示**,而文字则作为解释与补充。
如果你在阅读本书时,发现某段内容提供了如下图所示的动画图解,**请以图为主、以文字为辅**,综合两者来理解内容。 如果你在阅读本书时,发现某段内容提供了如下图所示的动画图解,**请以图为主、以文字为辅**,综合两者来理解内容。
![动画图解示例](../index.assets/animation.gif) ![动画图解示例](../index.assets/animation.gif)

@ -49,7 +49,7 @@
[file]{binary_search}-[class]{}-[func]{binary_search} [file]{binary_search}-[class]{}-[func]{binary_search}
``` ```
**时间复杂度为 $O(\log n)$** :在二分循环中,区间每轮缩小一半,循环次数为 $\log_2 n$ 。 **时间复杂度为 $O(\log n)$** :在二分循环中,区间每轮缩小一半,因此循环次数为 $\log_2 n$ 。
**空间复杂度为 $O(1)$** :指针 $i$ 和 $j$ 使用常数大小空间。 **空间复杂度为 $O(1)$** :指针 $i$ 和 $j$ 使用常数大小空间。

@ -17,7 +17,7 @@
1. 输入数组并建立大顶堆。完成后,最大元素位于堆顶。 1. 输入数组并建立大顶堆。完成后,最大元素位于堆顶。
2. 将堆顶元素(第一个元素)与堆底元素(最后一个元素)交换。完成交换后,堆的长度减 $1$ ,已排序元素数量加 $1$ 。 2. 将堆顶元素(第一个元素)与堆底元素(最后一个元素)交换。完成交换后,堆的长度减 $1$ ,已排序元素数量加 $1$ 。
3. 从堆顶元素开始,从顶到底执行堆化操作(Sift Down。完成堆化后堆的性质得到修复。 3. 从堆顶元素开始,从顶到底执行堆化操作(sift down。完成堆化后堆的性质得到修复。
4. 循环执行第 `2.` 步和第 `3.` 步。循环 $n - 1$ 轮后,即可完成数组排序。 4. 循环执行第 `2.` 步和第 `3.` 步。循环 $n - 1$ 轮后,即可完成数组排序。
!!! tip !!! tip

@ -377,7 +377,7 @@
综上,我们不能简单地确定哪种实现更加节省内存,需要针对具体情况进行分析。 综上,我们不能简单地确定哪种实现更加节省内存,需要针对具体情况进行分析。
## 栈典型应用 ## 栈典型应用
- **浏览器中的后退与前进、软件中的撤销与反撤销**。每当我们打开新的网页,浏览器就会对上一个网页执行入栈,这样我们就可以通过后退操作回到上一个网页。后退操作实际上是在执行出栈。如果要同时支持后退和前进,那么需要两个栈来配合实现。 - **浏览器中的后退与前进、软件中的撤销与反撤销**。每当我们打开新的网页,浏览器就会对上一个网页执行入栈,这样我们就可以通过后退操作回到上一个网页。后退操作实际上是在执行出栈。如果要同时支持后退和前进,那么需要两个栈来配合实现。
- **程序内存管理**。每次调用函数时,系统都会在栈顶添加一个栈帧,用于记录函数的上下文信息。在递归函数中,向下递推阶段会不断执行入栈操作,而向上回溯阶段则会不断执行出栈操作。 - **程序内存管理**。每次调用函数时,系统都会在栈顶添加一个栈帧,用于记录函数的上下文信息。在递归函数中,向下递推阶段会不断执行入栈操作,而向上回溯阶段则会不断执行出栈操作。

@ -20,7 +20,7 @@
**Q**:双向队列像是两个栈拼接在了一起,它的用途是什么? **Q**:双向队列像是两个栈拼接在了一起,它的用途是什么?
双向队列就像是栈和队列的组合或两个栈拼在了一起。它表现的是栈 + 队列的逻辑,因此可以实现栈与队列的所有应用,并且更加灵活。 双向队列就像是栈和队列的组合或两个栈拼在了一起。它表现的是栈 + 队列的逻辑,因此可以实现栈与队列的所有应用,并且更加灵活。
**Q**撤销undo和反撤销redo具体是如何实现的 **Q**撤销undo和反撤销redo具体是如何实现的

@ -14,7 +14,7 @@
## AVL 树常见术语 ## AVL 树常见术语
AVL 树既是二叉搜索树也是平衡二叉树,同时满足这两类二叉树的所有性质,因此也被称为「平衡二叉搜索树 balanced binary search tree」。 AVL 树既是二叉搜索树也是平衡二叉树,同时满足这两类二叉树的所有性质,因此也被称为「平衡二叉搜索树 balanced binary search tree」。
### 节点高度 ### 节点高度

@ -156,7 +156,7 @@ hide:
</a> </a>
</p> </p>
本书的代码审阅工作由 codingonion、Gonglja、gvenusleo、hpstory、justintse、krahets、night-cruise、nuomi1 和 Reanon 完成(按照首字母顺序排列)。感谢他们付出的时间与精力,正是他们确保了各语言代码的规范与统一。 本书的代码审阅工作由 codingonion、Gonglja、gvenusleo、hpstory、justin-tse、krahets、night-cruise、nuomi1 和 Reanon 完成(按照首字母顺序排列)。感谢他们付出的时间与精力,正是他们确保了各语言代码的规范与统一。
<div class="center-table"> <div class="center-table">
<table style="border: none;"> <table style="border: none;">

@ -9,7 +9,7 @@ docs_dir: build/docs-en
site_dir: site/en site_dir: site/en
# Repository # Repository
edit_uri: tree/main/docs-en edit_uri: tree/main/docs-en
version: 1.0.0b6 version: 1.0.0
# Configuration # Configuration
theme: theme:

@ -9,7 +9,7 @@ site_dir: site
repo_name: krahets/hello-algo repo_name: krahets/hello-algo
repo_url: https://github.com/krahets/hello-algo repo_url: https://github.com/krahets/hello-algo
edit_uri: tree/main/docs edit_uri: tree/main/docs
version: 1.0.0b6 version: 1.0.0
# Copyright # Copyright
copyright: Copyright &copy; 2022 - 2024 Krahets copyright: Copyright &copy; 2022 - 2024 Krahets

Loading…
Cancel
Save