Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
48f666a
docs: add GUIDELINES.md
Lingxuan-Ye Feb 5, 2026
56b2f49
build: bump edition to `"2024"`
Lingxuan-Ye Jan 20, 2026
a838f54
build: update dependency
Lingxuan-Ye Jan 20, 2026
9077815
feat: add support modules
Lingxuan-Ye Feb 5, 2026
7242649
fix: remove extra asterisks turning comment into outer doc comment
Lingxuan-Ye Feb 5, 2026
81ffbfe
refactor: adjust visibility according to codes/rust/GUIDELINES.md
Lingxuan-Ye Feb 5, 2026
0a09bcb
refactor: use a more intuitive way to join strings
Lingxuan-Ye Feb 5, 2026
a647b7e
perf: eliminate unnecessary branch jump in `Option::unwrap`
Lingxuan-Ye Feb 5, 2026
dc5ea1d
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
72232ee
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
cb80ebe
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
1870e88
refactor: replace all `n` types with `usize`
Lingxuan-Ye Feb 5, 2026
9080fb4
refactor: simplify code
Lingxuan-Ye Feb 5, 2026
e303758
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
09839e3
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
560e79c
refactor: simplify code
Lingxuan-Ye Feb 5, 2026
de9e7c3
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
86b72d0
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
cf8163b
fix: resolve a bug where capacity remained 0 when supposed to grow
Lingxuan-Ye Feb 5, 2026
99fcfed
refactor: replace field `extend_ratio` with associated constant `EXTE…
Lingxuan-Ye Feb 5, 2026
ca4b3d3
refactor: rewrite formatted output logic
Lingxuan-Ye Feb 5, 2026
3681662
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
1a57965
refactor: rewrite `LinkedListStack::pop` and `LinkedListStack::to_array`
Lingxuan-Ye Feb 5, 2026
9321f08
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
981797a
refactor: rewrite formatted output logic
Lingxuan-Ye Feb 5, 2026
1849698
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
532750a
refactor: simplify code
Lingxuan-Ye Feb 5, 2026
f223a46
refactor: simplify formatted output logic
Lingxuan-Ye Feb 5, 2026
7f3cb24
refactor: rewrite `LinkedListQueue::pop` and `LinkedListQueue::to_array`
Lingxuan-Ye Feb 5, 2026
7d3c628
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
1ee8012
refactor: rewrite formatted output logic
Lingxuan-Ye Feb 5, 2026
9ad1178
refactor: remove unnecessary trait field and trait bound
Lingxuan-Ye Feb 5, 2026
8d8005c
refactor: rewrite formatted output logic
Lingxuan-Ye Feb 5, 2026
ac7b05a
refactor: simplify formatted output logic
Lingxuan-Ye Feb 5, 2026
41a21ce
refactor: replace trait bound `Copy` with `Clone` and narrow its scope
Lingxuan-Ye Feb 5, 2026
0ef7120
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
92f52b3
refactor: rewrite formatted output logic
Lingxuan-Ye Feb 5, 2026
deda87c
refactor: rewrite for readability and consistency
Lingxuan-Ye Feb 5, 2026
a9fc04c
refactor: rewrite formatted output logic
Lingxuan-Ye Feb 5, 2026
96c8604
refactor: decouple binary crates
Lingxuan-Ye Feb 5, 2026
7d57c93
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
1be0d25
refactor: change method signatures to follow best practices
Lingxuan-Ye Feb 5, 2026
05e6928
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
1257068
refactor: reorder methods
Lingxuan-Ye Feb 5, 2026
41e9a44
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
ea0e0cf
refactor: replace fields `load_thres` and `extend_ratio` with associa…
Lingxuan-Ye Feb 5, 2026
ae5855e
refactor: reimplement `HashMapOpenAddressing` with enum `Bucket`
Lingxuan-Ye Feb 5, 2026
4b2559f
refactor: replace fields `load_thres` and `extend_ratio` with associa…
Lingxuan-Ye Feb 5, 2026
52e41ca
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
81925ae
refactor: simplify formatted output logic
Lingxuan-Ye Feb 5, 2026
ba18258
refactor: improve readability
Lingxuan-Ye Feb 5, 2026
abe3aa5
refactor: replace `hello_algo_rust::include::tree_node::TreeNode` wit…
Lingxuan-Ye Feb 5, 2026
f1beb58
refactor: unify `root` types for consistency
Lingxuan-Ye Feb 5, 2026
dd02f9c
refactor: replace all index types with `usize`
Lingxuan-Ye Feb 5, 2026
a92c2ec
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
b23f33e
perf: eliminate overhead from unnecessary unwraps, Rc cloning/droppin…
Lingxuan-Ye Feb 5, 2026
ccd1608
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
4d655ea
perf: eliminate overhead from unnecessary Rc cloning/dropping and Ref…
Lingxuan-Ye Feb 5, 2026
ab7ef42
refactor: simplify formatted output logic
Lingxuan-Ye Feb 5, 2026
fb25149
refactor: improve readability
Lingxuan-Ye Feb 5, 2026
6abcb05
fix: prevent `top_k_heap` from panicking when `k` is zero
Lingxuan-Ye Feb 5, 2026
749b3f8
refactor: change matrix element type to `bool`
Lingxuan-Ye Feb 5, 2026
6355048
refactor: decouple binary crates
Lingxuan-Ye Feb 5, 2026
0e11434
refactor: change neighbor list to `HashSet`
Lingxuan-Ye Feb 5, 2026
6e448b7
refactor: decouple binary crates
Lingxuan-Ye Feb 5, 2026
41f7004
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
16289f1
refactor: decouple binary crates and replace all return types with `O…
Lingxuan-Ye Feb 5, 2026
4f05b17
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
555c99f
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
9c44cdb
refactor: adjust comments and simplify formatted output logic
Lingxuan-Ye Feb 5, 2026
4b4a9ad
refactor: replace all index types with `usize`
Lingxuan-Ye Feb 5, 2026
5f58d0e
refactor: change method signatures to prevent out-of-bounds errors
Lingxuan-Ye Feb 5, 2026
d5a50ef
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
d65039f
refactor: change method signatures to prevent out-of-bounds errors
Lingxuan-Ye Feb 5, 2026
89bd4a5
refactor: change method signatures to prevent out-of-bounds errors
Lingxuan-Ye Feb 5, 2026
5db98b3
refactor: use `f64::total_cmp`for float sorting to follow best practices
Lingxuan-Ye Feb 5, 2026
88de845
refactor: replace num type with `u32` to prevent invalid inputs
Lingxuan-Ye Feb 5, 2026
34c117f
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
819aeea
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
32e6dd6
refactor: replace all index types with `usize`
Lingxuan-Ye Feb 5, 2026
824b5f2
refactor: replace all index types with `usize`
Lingxuan-Ye Feb 5, 2026
f7c6b53
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
573939b
refactor: replace the type of `i` with `usize` to avoid truncation
Lingxuan-Ye Feb 5, 2026
961ca96
refactor: simplify code and improve consistency
Lingxuan-Ye Feb 5, 2026
4870225
refactor: rewrite to conform to template code
Lingxuan-Ye Feb 5, 2026
9ff5ba3
refactor: improve readability
Lingxuan-Ye Feb 5, 2026
d8e47e9
refactor: trivial changes
Lingxuan-Ye Feb 5, 2026
cc2a684
perf: eliminate unnecessary heap allocation for strings
Lingxuan-Ye Feb 5, 2026
2591f42
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
79f744f
refactor: replace all integer types with `u32`
Lingxuan-Ye Feb 5, 2026
84121e3
perf: eliminate unnecessary heap allocations
Lingxuan-Ye Feb 5, 2026
00a2f3a
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
933b783
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
10d0b0b
refactor: replace all integer types with `u32`
Lingxuan-Ye Feb 5, 2026
7c2e999
fix: resolve warnings
Lingxuan-Ye Feb 5, 2026
0411e4c
refactor: replace cost type with `u32` and index type with `usize`
Lingxuan-Ye Feb 5, 2026
7b9a668
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
ce698aa
refactor: replace all integer types except indices with `u32`
Lingxuan-Ye Feb 5, 2026
e9244fc
perf: replace strings with char arrays for O(1) access
Lingxuan-Ye Feb 5, 2026
f820a04
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
de91999
refactor: replace all input integer types with `u32` and all return t…
Lingxuan-Ye Feb 5, 2026
7a58853
fix: resolve warning
Lingxuan-Ye Feb 5, 2026
21b3334
refactor: replace all integer types with `u32`
Lingxuan-Ye Feb 5, 2026
bf33f65
refactor: replace all input integer types with `u32` and return type …
Lingxuan-Ye Feb 5, 2026
2ae41a7
refactor: replace all integer types with `u32`
Lingxuan-Ye Feb 5, 2026
663e7d1
refactor!: remove mod `include`
Lingxuan-Ye Feb 5, 2026
b2b4b18
docs: remove leading underscores
Lingxuan-Ye Feb 5, 2026
6659238
docs: remove redundant code
Lingxuan-Ye Feb 5, 2026
ec03329
docs: reword
Lingxuan-Ye Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions codes/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "hello-algo-rust"
version = "0.1.0"
edition = "2021"
edition = "2024"
publish = false

# Run Command: cargo run --bin time_complexity
Expand Down Expand Up @@ -410,4 +410,4 @@ name = "max_product_cutting"
path = "chapter_greedy/max_product_cutting.rs"

[dependencies]
rand = "0.8.5"
rand = "0.9.2"
63 changes: 63 additions & 0 deletions codes/rust/GUIDELINES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# 维护指南

## 工具准备

[Clippy] 是 Rust 工具链中的可选组件,可以帮助我们发现和修复代码中的常见问题。请确保在提交代码之前运行 Clippy 并修复所有警告。

### 安装

```shell
rustup update
rustup component add clippy
```

### 使用

```shell
cargo clippy
```

或配合各编辑器的 rust-analyzer 插件使用。

## 术语

- **示例代码**:会被嵌入到《Hello 算法》中渲染输出的代码。
- **非示例代码**:不会被嵌入到《Hello 算法》中渲染输出的代码,例如辅助函数、辅助类型、测试代码等。

## 代码风格

代码风格应遵循一致、清晰和可维护的原则。当这些原则存在冲突时,请按以下优先级处理:

1. **示例代码**应与《Hello 算法》中的文本和图片保持一致,不宜改变其中出现的标识符和执行顺序,不得改变代码逻辑。例如,若书中使用 `i` 和 `p` 命名节点索引和父节点索引,避免重命名为 `index` 和 `parent`,如果实在影响阅读,应在函数签名或函数体内注释并重绑定;若书中使用递归实现,不得改为迭代实现。

2. 代码应满足 *[Rust Style Guide]* 和 Clippy 的建议。如果修复 lint 会导致与第一条冲突,则应使用属性 `allow(...)` 以显式地移除警告。外部属性(标柱跟随项)的语法为 `#[attr]`,内部属性(标注所在项)的语法为 `#![attr]`,除了以文件为单位的模块顶层以外,不应使用内部属性。属性的作用范围应该尽可能的小,但不得小到单独作用于语句和表达式上;允许的类型应该尽可能地精确,例如,未使用的函数、结构体等顶层项应使用 `allow(dead_code)`,未使用的变量应使用 `allow(unused_variables)`。避免使用 `allow(unused)`,如使用,应在提交代码前短暂地移除该属性并解决被意外忽略的警告。

3. 代码建议与其他语言的实现保持一致。因为不同语言的规范和惯例具有较大的差异,不应强求这种一致性。

## 常见情况的处理建议

- **公共项**:应作为 lib crate `hello_algo_rust` 的公共接口,放在 `src` 目录下。项目内的其他所有代码均为 bin crates,它们作为依赖链的最下游,不应作为依赖项被其他 crate「挂载」为模块。目前 Cargo 并没有阻止这种做法,甚至允许一个文件被多次「挂载」,但这是一种典型的反模式,应当避免。

- **可见性**:**示例代码**全部位于 bin crates,原则上不会被其他地方使用,最大可见性本应为 `pub(crate)`,在 crate 顶层无需被可见性修饰符修饰;然而,「实现某种数据结构或算法」暗示着代码将作为某种公开接口供下游使用,为了表达这种意图,以及区分公开接口和内部实现细节,**示例代码**中原则上是公开接口的部分应使用 `pub` 修饰符,是内部实现细节的部分不使用可见性修饰符。可见性修饰符中不得出现范围参数,例如 `pub(super)`、`pub(in some::path)` 等。

- **导入**:常量、静态量、类型别名、结构体、枚举、trait 等可直接导入,函数应导入上级模块并以其为前缀使用。

- **类型别名**:对于**示例代码**,如果类型别名不会被输出,不建议使用类型别名,例如 `type NodeRef = Rc<RefCell<Node>>;`。

- **`val` 类型**:对于**示例代码**,数据结构的 `val` 字段类型应使用默认整型 `i32`,不建议使用泛型参数,不得使用复杂约束的泛型参数。

- **索引、长度及迭代计数类型**:对于可能不存在的索引,使用 `Option<usize>` 类型,其他所有关于索引、长度及迭代计数的代码都应该使用 `usize` 类型。这不是代码风格问题,而是代码正确性问题。永远不应该使用 `i32` 作为索引类型,因为即使在 32 位平台,`i32` 也有一半的合法位置无法索引。具体原因涉及指针偏移、内存分配以及零大小类型,详见 *[Rustonomicon]*。

- **非法值**:不得使用 `-1` 作为非法值,应该使用 `Option<T>` 类型的 `None` 来标记非法值。

- **溢出**:对于**示例代码**,不检查因累加造成的最终结果溢出,因为这是类型表达能力的限制,应任其 panic 并终止程序;对于索引偏移等操作,应处理溢出行为,比如检查并提前返回、显式回绕等,因为这是算法正常运行必须处理的边界条件。不得将 usize 转换为 isize 甚至 i32 来避免减法溢出,可以但不鼓励将 usize 转换为 i128 来避免溢出。

- **未使用的变量**:对于**示例代码**,应使用 `allow(unused_variables)` 移除警告;对于**非示例代码**,应使用 `_` 为前缀重命名变量。

- **格式化输出**:对于**非示例代码**,应实现 `std::fmt::Display` trait 以提供自定义的格式化输出,避免自定义 `print` 等函数或方法。出现在**示例代码**中的 `print` 函数或方法应维持原状。

- **注释**:注释风格应遵循 *[Rust Style Guide]*,避免使用多行注释,应使用多行的单行注释。

[Clippy]: https://github.com/rust-lang/rust-clippy
[Rust Style Guide]: https://doc.rust-lang.org/style-guide/
[Rustonomicon]: https://doc.rust-lang.org/stable/nomicon/vec/vec-alloc.html#allocating-memory
54 changes: 26 additions & 28 deletions codes/rust/chapter_array_and_linkedlist/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@
* Author: xBLACICEx (xBLACKICEx@outlook.com), codingonion (coderonion@gmail.com)
*/

use hello_algo_rust::include::print_util;
use rand::Rng;

/* 随机访问元素 */
fn random_access(nums: &[i32]) -> i32 {
pub fn random_access(nums: &[i32]) -> i32 {
// 在区间 [0, nums.len()) 中随机抽取一个数字
let random_index = rand::thread_rng().gen_range(0..nums.len());
let random_index = rand::rng().random_range(0..nums.len());
// 获取并返回随机元素
let random_num = nums[random_index];
random_num
nums[random_index]
}

/* 扩展数组长度 */
fn extend(nums: &[i32], enlarge: usize) -> Vec<i32> {
pub fn extend(nums: &[i32], enlarge: usize) -> Vec<i32> {
// 初始化一个扩展长度后的数组
let mut res: Vec<i32> = vec![0; nums.len() + enlarge];
// 将原数组中的所有元素复制到新
Expand All @@ -28,39 +26,44 @@ fn extend(nums: &[i32], enlarge: usize) -> Vec<i32> {
}

/* 在数组的索引 index 处插入元素 num */
fn insert(nums: &mut [i32], num: i32, index: usize) {
pub fn insert(nums: &mut [i32], num: i32, index: usize) {
// 把索引 index 以及之后的所有元素向后移动一位
for i in (index + 1..nums.len()).rev() {
for i in ((index + 1)..nums.len()).rev() {
nums[i] = nums[i - 1];
}
// 将 num 赋给 index 处的元素
nums[index] = num;
}

/* 删除索引 index 处的元素 */
fn remove(nums: &mut [i32], index: usize) {
pub fn remove(nums: &mut [i32], index: usize) {
// 把索引 index 之后的所有元素向前移动一位
for i in index..nums.len() - 1 {
for i in index..(nums.len() - 1) {
nums[i] = nums[i + 1];
}
}

/* 遍历数组 */
fn traverse(nums: &[i32]) {
let mut _count = 0;
#[allow(unused_variables)]
#[allow(unused_assignments)]
#[allow(clippy::needless_range_loop)]
pub fn traverse(nums: &[i32]) {
let mut count = 0;
// 通过索引遍历数组
for i in 0..nums.len() {
_count += nums[i];
count += nums[i];
}
// 直接遍历数组元素
_count = 0;
count = 0;
for &num in nums {
_count += num;
count += num;
}
}

/* 在数组中查找指定元素 */
fn find(nums: &[i32], target: i32) -> Option<usize> {
#[allow(clippy::manual_find)]
#[allow(clippy::needless_range_loop)]
pub fn find(nums: &[i32], target: i32) -> Option<usize> {
for i in 0..nums.len() {
if nums[i] == target {
return Some(i);
Expand All @@ -73,39 +76,34 @@ fn find(nums: &[i32], target: i32) -> Option<usize> {
fn main() {
/* 初始化数组 */
let arr: [i32; 5] = [0; 5];
print!("数组 arr = ");
print_util::print_array(&arr);
println!("数组 arr = {arr:?}");
// 在 Rust 中,指定长度时([i32; 5])为数组,不指定长度时(&[i32])为切片
// 由于 Rust 的数组被设计为在编译期确定长度,因此只能使用常量来指定长度
// Vector 是 Rust 一般情况下用作动态数组的类型
// 为了方便实现扩容 extend() 方法,以下将 vector 看作数组(array)
let nums: Vec<i32> = vec![1, 3, 2, 5, 4];
print!("\n数组 nums = ");
print_util::print_array(&nums);
println!("数组 nums = {nums:?}");

// 随机访问
let random_num = random_access(&nums);
println!("\n在 nums 中获取随机元素 {}", random_num);
println!(" nums 中获取随机元素 {random_num}");

// 长度扩展
let mut nums: Vec<i32> = extend(&nums, 3);
print!("将数组长度扩展至 8 ,得到 nums = ");
print_util::print_array(&nums);
print!("将数组长度扩展至 8 ,得到 nums = {nums:?}");

// 插入元素
insert(&mut nums, 6, 3);
print!("\n在索引 3 处插入数字 6 ,得到 nums = ");
print_util::print_array(&nums);
println!("在索引 3 处插入数字 6 ,得到 nums = {nums:?}");

// 删除元素
remove(&mut nums, 2);
print!("\n删除索引 2 处的元素,得到 nums = ");
print_util::print_array(&nums);
println!("删除索引 2 处的元素,得到 nums = {nums:?}");

// 遍历数组
traverse(&nums);

// 查找元素
let index = find(&nums, 3).unwrap();
println!("\n在 nums 中查找元素 3 ,得到索引 = {}", index);
println!(" nums 中查找元素 3 ,得到索引 = {index}");
}
71 changes: 32 additions & 39 deletions codes/rust/chapter_array_and_linkedlist/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Author: codingonion (coderonion@gmail.com)
*/

use hello_algo_rust::include::{print_util, ListNode};
use hello_algo_rust::linked_list::{LinkedList, ListNode};
use std::cell::RefCell;
use std::rc::Rc;

Expand All @@ -28,39 +28,36 @@ pub fn remove<T>(n0: &Rc<RefCell<ListNode<T>>>) {
}

/* 访问链表中索引为 index 的节点 */
pub fn access<T>(head: Rc<RefCell<ListNode<T>>>, index: i32) -> Option<Rc<RefCell<ListNode<T>>>> {
fn dfs<T>(
head: Option<&Rc<RefCell<ListNode<T>>>>,
index: i32,
) -> Option<Rc<RefCell<ListNode<T>>>> {
if index <= 0 {
return head.cloned();
}

if let Some(node) = head {
dfs(node.borrow().next.as_ref(), index - 1)
} else {
None
}
pub fn access<T>(
head: &Rc<RefCell<ListNode<T>>>,
index: usize,
) -> Option<Rc<RefCell<ListNode<T>>>> {
if index == 0 {
return Some(head.clone());
}

dfs(Some(head).as_ref(), index)
let mut next = head.borrow().next.clone();
for _ in 1..index {
let node = next?;
next = node.borrow().next.clone();
}
next
}

/* 在链表中查找值为 target 的首个节点 */
pub fn find<T: PartialEq>(head: Rc<RefCell<ListNode<T>>>, target: T) -> i32 {
fn find<T: PartialEq>(head: Option<&Rc<RefCell<ListNode<T>>>>, target: T, idx: i32) -> i32 {
if let Some(node) = head {
if node.borrow().val == target {
return idx;
}
return find(node.borrow().next.as_ref(), target, idx + 1);
} else {
-1
pub fn find<T: PartialEq>(head: &Rc<RefCell<ListNode<T>>>, target: T) -> Option<usize> {
if head.borrow().val == target {
return Some(0);
}
let mut next = head.borrow().next.clone();
let mut index = 1;
while let Some(node) = next {
if node.borrow().val == target {
return Some(index);
}
next = node.borrow().next.clone();
index += 1;
}

find(Some(head).as_ref(), target, 0)
None
}

/* Driver Code */
Expand All @@ -77,24 +74,20 @@ fn main() {
n1.borrow_mut().next = Some(n2.clone());
n2.borrow_mut().next = Some(n3.clone());
n3.borrow_mut().next = Some(n4.clone());
print!("初始化的链表为 ");
print_util::print_linked_list(&n0);
println!("初始化的链表为 {}", n0.display_as_list());

/* 插入节点 */
insert(&n0, ListNode::new(0));
print!("插入节点后的链表为 ");
print_util::print_linked_list(&n0);

println!("插入节点后的链表为 {}", n0.display_as_list());
/* 删除节点 */
remove(&n0);
print!("删除节点后的链表为 ");
print_util::print_linked_list(&n0);
println!("删除节点后的链表为 {}", n0.display_as_list());

/* 访问节点 */
let node = access(n0.clone(), 3);
println!("链表中索引 3 处的节点的值 = {}", node.unwrap().borrow().val);
let node = access(&n0, 3).unwrap();
println!("链表中索引 3 处的节点的值 = {}", node.borrow().val);

/* 查找节点 */
let index = find(n0.clone(), 2);
println!("链表中值为 2 的节点的索引 = {}", index);
let index = find(&n0, 2).unwrap();
println!("链表中值为 2 的节点的索引 = {index}");
}
45 changes: 19 additions & 26 deletions codes/rust/chapter_array_and_linkedlist/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,62 @@
* Created Time: 2023-01-18
* Author: xBLACICEx (xBLACKICEx@outlook.com), codingonion (coderonion@gmail.com)
*/
use hello_algo_rust::include::print_util;

/* Driver Code */
#[allow(unused_variables)]
#[allow(unused_assignments)]
#[allow(clippy::needless_range_loop)]
fn main() {
// 初始化列表
let mut nums: Vec<i32> = vec![1, 3, 2, 5, 4];
print!("列表 nums = ");
print_util::print_array(&nums);
println!("列表 nums = {nums:?}");

// 访问元素
let num = nums[1];
println!("\n访问索引 1 处的元素,得到 num = {num}");
println!("访问索引 1 处的元素,得到 num = {num}");

// 更新元素
nums[1] = 0;
print!("将索引 1 处的元素更新为 0 ,得到 nums = ");
print_util::print_array(&nums);
println!("将索引 1 处的元素更新为 0 ,得到 nums = {nums:?}");

// 清空列表
nums.clear();
print!("\n清空列表后 nums = ");
print_util::print_array(&nums);
println!("清空列表后 nums = {nums:?}");

// 在尾部添加元素
nums.push(1);
nums.push(3);
nums.push(2);
nums.push(5);
nums.push(4);
print!("\n添加元素后 nums = ");
print_util::print_array(&nums);
println!("添加元素后 nums = {nums:?}");

// 在中间插入元素
nums.insert(3, 6);
print!("\n在索引 3 处插入数字 6 ,得到 nums = ");
print_util::print_array(&nums);
println!("在索引 3 处插入数字 6 ,得到 nums = {nums:?}");

// 删除元素
nums.remove(3);
print!("\n删除索引 3 处的元素,得到 nums = ");
print_util::print_array(&nums);
println!("删除索引 3 处的元素,得到 nums = {nums:?}");

// 通过索引遍历列表
let mut _count = 0;
let mut count = 0;
for i in 0..nums.len() {
_count += nums[i];
count += nums[i];
}

// 直接遍历列表元素
_count = 0;
let mut count = 0;
for x in &nums {
_count += x;
count += x;
}

// 拼接两个列表
let mut nums1 = vec![6, 8, 7, 10, 9];
nums.append(&mut nums1); // append(移动) 之后 nums1 为空!

// nums.extend(&nums1); // extend(借用) nums1 能继续使用
print!("\n将列表 nums1 拼接到 nums 之后,得到 nums = ");
print_util::print_array(&nums);
let nums1 = vec![6, 8, 7, 10, 9];
nums.extend(nums1);
println!("将列表 nums1 拼接到 nums 之后,得到 nums = {nums:?}");

// 排序列表
nums.sort();
print!("\n排序列表后 nums = ");
print_util::print_array(&nums);
println!("排序列表后 nums = {nums:?}");
}
Loading