Update the book based on the revised second edition (#1014)

* Revised the book

* Update the book with the second revised edition

* Revise base on the manuscript of the first edition
This commit is contained in:
Yudong Jin
2023-12-28 18:06:09 +08:00
committed by GitHub
parent 19dde675df
commit f68bbb0d59
261 changed files with 643 additions and 647 deletions

View File

@ -41,7 +41,7 @@ impl MyList {
/* 访问元素 */
pub fn get(&self, index: usize) -> i32 {
// 索引如果越界则抛出异常,下同
// 索引如果越界则抛出异常,下同
if index >= self.size {panic!("索引越界")};
return self.arr[index];
}
@ -89,13 +89,13 @@ impl MyList {
}
// 更新元素数量
self.size -= 1;
// 返回被删除元素
// 返回被删除元素
return num;
}
/* 列表扩容 */
pub fn extend_capacity(&mut self) {
// 新建一个长度为原数组 extend_ratio 倍的新数组,并将原数组拷贝到新数组
// 新建一个长度为原数组 extend_ratio 倍的新数组,并将原数组复制到新数组
let new_capacity = self.capacity * self.extend_ratio;
self.arr.resize(new_capacity, 0);
// 更新列表容量

View File

@ -18,10 +18,10 @@ fn backtrack(row: usize, n: usize, state: &mut Vec<Vec<String>>, res: &mut Vec<V
}
// 遍历所有列
for col in 0..n {
// 计算该格子对应的主对角线和对角线
// 计算该格子对应的主对角线和对角线
let diag1 = row + n - 1 - col;
let diag2 = row + col;
// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后
// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后
if !cols[col] && !diags1[diag1] && !diags2[diag2] {
// 尝试:将皇后放置在该格子
state.get_mut(row).unwrap()[col] = "Q".into();
@ -48,7 +48,7 @@ fn n_queens(n: usize) -> Vec<Vec<Vec<String>>> {
}
let mut cols = vec![false; n]; // 记录列是否有皇后
let mut diags1 = vec![false; 2 * n - 1]; // 记录主对角线上是否有皇后
let mut diags2 = vec![false; 2 * n - 1]; // 记录对角线上是否有皇后
let mut diags2 = vec![false; 2 * n - 1]; // 记录对角线上是否有皇后
let mut res: Vec<Vec<Vec<String>>> = Vec::new();
backtrack(0, n, &mut state, &mut res, &mut cols, &mut diags1, &mut diags2);

View File

@ -10,7 +10,7 @@ use std::collections::{HashSet, VecDeque};
use graph_adjacency_list::GraphAdjList;
use graph_adjacency_list::{Vertex, vets_to_vals, vals_to_vets};
/* 广度优先遍历 BFS */
/* 广度优先遍历 */
// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
fn graph_bfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {
// 顶点遍历序列
@ -62,7 +62,7 @@ fn main() {
println!("\n初始化后,图为");
graph.print();
/* 广度优先遍历 BFS */
/* 广度优先遍历 */
let res = graph_bfs(graph, v[0]);
println!("\n广度优先遍历BFS顶点序列为");
println!("{:?}", vets_to_vals(res));

View File

@ -10,7 +10,7 @@ use std::collections::HashSet;
use graph_adjacency_list::GraphAdjList;
use graph_adjacency_list::{Vertex, vets_to_vals, vals_to_vets};
/* 深度优先遍历 DFS 辅助函数 */
/* 深度优先遍历辅助函数 */
fn dfs(graph: &GraphAdjList, visited: &mut HashSet<Vertex>, res: &mut Vec<Vertex>, vet: Vertex) {
res.push(vet); // 记录访问顶点
visited.insert(vet); // 标记该顶点已被访问
@ -26,7 +26,7 @@ fn dfs(graph: &GraphAdjList, visited: &mut HashSet<Vertex>, res: &mut Vec<Vertex
}
}
/* 深度优先遍历 DFS */
/* 深度优先遍历 */
// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点
fn graph_dfs(graph: GraphAdjList, start_vet: Vertex) -> Vec<Vertex> {
// 顶点遍历序列
@ -54,7 +54,7 @@ fn main() {
println!("\n初始化后,图为");
graph.print();
/* 深度优先遍历 DFS */
/* 深度优先遍历 */
let res = graph_dfs(graph, v[0]);
println!("\n深度优先遍历DFS顶点序列为");
println!("{:?}", vets_to_vals(res));

View File

@ -6,7 +6,7 @@
/* 最大容量:贪心 */
fn max_capacity(ht: &[i32]) -> i32 {
// 初始化 i, j 分列数组两端
// 初始化 i, j,使其分列数组两端
let mut i = 0;
let mut j = ht.len() - 1;
// 初始最大容量为 0

View File

@ -85,7 +85,7 @@ fn main() {
map.print();
/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
// 向哈希表输入键 key ,得到值 value
let name = map.get(15937).unwrap();
println!("\n输入学号 15937 ,查询到姓名 {}", name);

View File

@ -24,7 +24,7 @@ pub fn main() {
print_util::print_hash_map(&map);
// 查询操作
// 向哈希表输入键 key ,得到值 value
// 向哈希表输入键 key ,得到值 value
let name = map.get(&15937).copied().unwrap();
println!("\n输入学号 15937 ,查询到姓名 {name}");

View File

@ -56,7 +56,7 @@ impl HashMapChaining {
}
}
// 若未找到 key 则返回 None
// 若未找到 key 则返回 None
None
}
@ -122,14 +122,14 @@ impl HashMapChaining {
let index = self.hash_func(key);
let bucket = &self.buckets[index];
// 遍历桶,若找到 key 则返回对应 val
// 遍历桶,若找到 key 则返回对应 val
for pair in bucket {
if pair.key == key {
return Some(&pair.val);
}
}
// 若未找到 key 则返回 None
// 若未找到 key 则返回 None
None
}
}
@ -150,7 +150,7 @@ pub fn main() {
map.print();
/* 查询操作 */
// 向哈希表输入键 key ,得到值 value
// 向哈希表输入键 key ,得到值 value
println!("\n输入学号 13276,查询到姓名 {}", match map.get(13276) {
Some(value) => value,
None => "Not a valid Key"

View File

@ -64,7 +64,7 @@ impl HashMapOpenAddressing {
if first_tombstone == -1 && self.buckets[index] == self.TOMBSTONE {
first_tombstone = index as i32;
}
// 计算桶索引,越过尾部返回头部
// 计算桶索引,越过尾部返回头部
index = (index + 1) % self.capacity;
}
// 若 key 不存在,则返回添加点的索引
@ -163,7 +163,7 @@ fn main() {
hashmap.print();
/* 查询操作 */
// 向哈希表输入键 key ,得到值 val
// 向哈希表输入键 key ,得到值 val
let name = hashmap.get(13276).unwrap();
println!("\n输入学号 13276 ,查询到姓名 {}", name);

View File

@ -24,17 +24,17 @@ impl MaxHeap {
heap
}
/* 获取左子节点索引 */
/* 获取左子节点索引 */
fn left(i: usize) -> usize {
2 * i + 1
}
/* 获取右子节点索引 */
/* 获取右子节点索引 */
fn right(i: usize) -> usize {
2 * i + 2
}
/* 获取父节点索引 */
/* 获取父节点索引 */
fn parent(i: usize) -> usize {
(i - 1) / 2 // 向下整除
}

View File

@ -37,7 +37,7 @@ fn bubble_sort_with_flag(nums: &mut [i32]) {
flag = true; // 记录交换元素
}
}
if !flag {break}; // 此轮冒泡未交换任何元素,直接跳出
if !flag {break}; // 此轮冒泡未交换任何元素,直接跳出
}
}

View File

@ -6,13 +6,13 @@
/* 合并左子数组和右子数组 */
fn merge(nums: &mut [i32], left: usize, mid: usize, right: usize) {
// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]
// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]
// 创建一个临时数组 tmp ,用于存放合并后的结果
let tmp_size = right - left + 1;
let mut tmp = vec![0; tmp_size];
// 初始化左子数组和右子数组的起始索引
let (mut i, mut j, mut k) = (left, mid + 1, 0);
// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中
// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中
while i <= mid && j <= right {
if nums[i] <= nums[j] {
tmp[k] = nums[j];

View File

@ -44,7 +44,7 @@ impl QuickSort {
struct QuickSortMedian;
impl QuickSortMedian {
/* 选取三个元素的中位数 */
/* 选取三个候选元素的中位数 */
fn median_three(nums: &mut [i32], left: usize, mid: usize, right: usize) -> usize {
// 此处使用异或运算来简化代码
// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1

View File

@ -53,7 +53,7 @@ impl ArrayDeque {
return
}
// 队首指针向左移动一位
// 通过取余操作实现 front 越过数组头部后回到尾部
// 通过取余操作实现 front 越过数组头部后回到尾部
self.front = self.index(self.front as i32 - 1);
// 将 num 添加至队首
self.nums[self.front] = num;
@ -66,7 +66,7 @@ impl ArrayDeque {
println!("双向队列已满");
return
}
// 计算尾指针,指向队尾索引 + 1
// 计算尾指针,指向队尾索引 + 1
let rear = self.index(self.front as i32 + self.que_size as i32);
// 将 num 添加至队尾
self.nums[rear] = num;

View File

@ -44,8 +44,8 @@ impl ArrayQueue {
println!("队列已满");
return;
}
// 计算尾指针,指向队尾索引 + 1
// 通过取余操作实现 rear 越过数组尾部后回到头部
// 计算尾指针,指向队尾索引 + 1
// 通过取余操作实现 rear 越过数组尾部后回到头部
let rear = (self.front + self.que_size) % self.que_capacity;
// 将 num 添加至队尾
self.nums[rear as usize] = num;
@ -55,7 +55,7 @@ impl ArrayQueue {
/* 出队 */
fn pop(&mut self) -> i32 {
let num = self.peek();
// 队首指针向后移动一位,若越过尾部则返回到数组头部
// 队首指针向后移动一位,若越过尾部则返回到数组头部
self.front = (self.front + 1) % self.que_capacity;
self.que_size -= 1;
num

View File

@ -39,7 +39,7 @@ impl<T: Copy> LinkedListQueue<T> {
/* 入队 */
pub fn push(&mut self, num: T) {
// 尾节点后添加 num
// 尾节点后添加 num
let new_rear = ListNode::new(num);
match self.rear.take() {
// 如果队列不为空,则将该节点添加到尾节点后

View File

@ -137,7 +137,7 @@ impl AVLTree {
fn insert_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {
match node {
Some(mut node) => {
/* 1. 查找插入位置并插入节点 */
/* 1. 查找插入位置并插入节点 */
match {
let node_val = node.borrow().val;
node_val
@ -175,7 +175,7 @@ impl AVLTree {
fn remove_helper(node: OptionTreeNodeRc, val: i32) -> OptionTreeNodeRc {
match node {
Some(mut node) => {
/* 1. 查找节点并删除 */
/* 1. 查找节点并删除 */
if val < node.borrow().val {
let left = node.borrow().left.clone();
node.borrow_mut().left = Self::remove_helper(left, val);