From 8a388d84227527c0d4426aeb76cb57e4787406b2 Mon Sep 17 00:00:00 2001 From: sjinzh <99076655+sjinzh@users.noreply.github.com> Date: Sun, 5 Feb 2023 16:25:42 +0800 Subject: [PATCH] update rust codes for hash_map, binary_search, bubble_sort, stack, queue (#330) * update rust codes * update rust codes * update rust codes * update and add rust codes for hash_map, binary_search, bubble_sort * update and add rust codes for hash_map, binary_search, bubble_sort * add rust codes for chapter stack * add rust codes for chapter queue * add rust codes for chapter deque --- codes/rust/.gitignore | 5 +- codes/rust/Cargo.lock | 82 ----------- codes/rust/Cargo.toml | 70 +++++++++- .../chapter_array_and_linkedlist/Cargo.toml | 16 --- .../chapter_array_and_linkedlist/array.rs | 27 ++-- .../rust/chapter_array_and_linkedlist/list.rs | 131 +++++++++--------- .../Cargo.toml | 21 --- .../leetcode_two_sum.rs | 29 ++-- .../time_complexity.rs | 34 ++--- .../worst_best_time_complexity.rs | 71 +++++----- codes/rust/chapter_hashing/hash_map.rs | 46 ++++++ codes/rust/chapter_searching/binary_search.rs | 59 ++++++++ codes/rust/chapter_sorting/bubble_sort.rs | 53 +++++++ codes/rust/chapter_stack_and_queue/deque.rs | 42 ++++++ codes/rust/chapter_stack_and_queue/queue.rs | 39 ++++++ codes/rust/chapter_stack_and_queue/stack.rs | 38 +++++ codes/rust/include/include.rs | 7 + codes/rust/include/print_util.rs | 37 +++++ codes/zig/chapter_stack_and_queue/deque.zig | 16 +-- codes/zig/chapter_stack_and_queue/queue.zig | 8 +- codes/zig/chapter_stack_and_queue/stack.zig | 8 +- 21 files changed, 559 insertions(+), 280 deletions(-) delete mode 100644 codes/rust/Cargo.lock delete mode 100644 codes/rust/chapter_array_and_linkedlist/Cargo.toml delete mode 100644 codes/rust/chapter_computational_complexity/Cargo.toml create mode 100644 codes/rust/chapter_hashing/hash_map.rs create mode 100644 codes/rust/chapter_searching/binary_search.rs create mode 100644 codes/rust/chapter_sorting/bubble_sort.rs create mode 100644 codes/rust/chapter_stack_and_queue/deque.rs create mode 100644 codes/rust/chapter_stack_and_queue/queue.rs create mode 100644 codes/rust/chapter_stack_and_queue/stack.rs create mode 100644 codes/rust/include/include.rs create mode 100644 codes/rust/include/print_util.rs diff --git a/codes/rust/.gitignore b/codes/rust/.gitignore index 106fe28c..44709884 100644 --- a/codes/rust/.gitignore +++ b/codes/rust/.gitignore @@ -1,3 +1,2 @@ -**/target -**/worst_best_time_complexity/ -**/time_complexity/ \ No newline at end of file +target/ +Cargo.lock \ No newline at end of file diff --git a/codes/rust/Cargo.lock b/codes/rust/Cargo.lock deleted file mode 100644 index 6de3eabd..00000000 --- a/codes/rust/Cargo.lock +++ /dev/null @@ -1,82 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chapter_array_and_linkedlist" -version = "0.1.0" -dependencies = [ - "rand", -] - -[[package]] -name = "chapter_computational_complexity" -version = "0.1.0" -dependencies = [ - "rand", -] - -[[package]] -name = "getrandom" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/codes/rust/Cargo.toml b/codes/rust/Cargo.toml index c2e0db42..a963335d 100644 --- a/codes/rust/Cargo.toml +++ b/codes/rust/Cargo.toml @@ -1,6 +1,66 @@ +[package] +name = "hello-algo-rust" +version = "0.1.0" +edition = "2021" -[workspace] -members = [ - "chapter_computational_complexity", - "chapter_array_and_linkedlist" -] \ No newline at end of file +[lib] +name = "inc" +path = "include/include.rs" + +# Run Command: cargo run --bin time_complexity +[[bin]] +name = "time_complexity" +path = "chapter_computational_complexity/time_complexity.rs" + +# Run Command: cargo run --bin worst_best_time_complexity +[[bin]] +name = "worst_best_time_complexity" +path = "chapter_computational_complexity/worst_best_time_complexity.rs" + +# Run Command: cargo run --bin leetcode_two_sum +[[bin]] +name = "leetcode_two_sum" +path = "chapter_computational_complexity/leetcode_two_sum.rs" + +# Run Command: cargo run --bin array +[[bin]] +name = "array" +path = "chapter_array_and_linkedlist/array.rs" + +# Run Command: cargo run --bin list +[[bin]] +name = "list" +path = "chapter_array_and_linkedlist/list.rs" + +# Run Command: cargo run --bin stack +[[bin]] +name = "stack" +path = "chapter_stack_and_queue/stack.rs" + +# Run Command: cargo run --bin queue +[[bin]] +name = "queue" +path = "chapter_stack_and_queue/queue.rs" + +# Run Command: cargo run --bin deque +[[bin]] +name = "deque" +path = "chapter_stack_and_queue/deque.rs" + +# Run Command: cargo run --bin hash_map +[[bin]] +name = "hash_map" +path = "chapter_hashing/hash_map.rs" + +# Run Command: cargo run --bin binary_search +[[bin]] +name = "binary_search" +path = "chapter_searching/binary_search.rs" + +# Run Command: cargo run --bin bubble_sort +[[bin]] +name = "bubble_sort" +path = "chapter_sorting/bubble_sort.rs" + +[dependencies] +rand = "0.8.5" \ No newline at end of file diff --git a/codes/rust/chapter_array_and_linkedlist/Cargo.toml b/codes/rust/chapter_array_and_linkedlist/Cargo.toml deleted file mode 100644 index a83a67b0..00000000 --- a/codes/rust/chapter_array_and_linkedlist/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "chapter_array_and_linkedlist" -version = "0.1.0" -edition = "2021" - - -[[bin]] -name = "array" -path = "array.rs" - -[[bin]] -name = "list" -path = "list.rs" - -[dependencies] -rand = "0.8.5" diff --git a/codes/rust/chapter_array_and_linkedlist/array.rs b/codes/rust/chapter_array_and_linkedlist/array.rs index e23c6a4f..a52d0db8 100644 --- a/codes/rust/chapter_array_and_linkedlist/array.rs +++ b/codes/rust/chapter_array_and_linkedlist/array.rs @@ -1,7 +1,7 @@ /** * File: array.rs * Created Time: 2023-01-15 - * Author: xBLACICEx (xBLACKICEx@outlook.com) + * Author: xBLACICEx (xBLACKICEx@outlook.com), sjinzh (sjinzh@gmail.com) */ /* 随机返回一个数组元素 */ @@ -15,7 +15,7 @@ fn random_access(nums: &[i32]) -> i32 { /* 扩展数组长度 */ fn extend(nums: Vec, enlarge: usize) -> Vec { - // 创建一个长度为 nums.len() + enlarge 的新 Vec + // 初始化一个扩展长度后的数组 let mut res: Vec = vec![0; nums.len() + enlarge]; // 将原数组中的所有元素复制到新 for i in 0..nums.len() { @@ -70,33 +70,38 @@ fn find(nums: &[i32], target: i32) -> Option { /* Driver Code */ fn main() { let arr = [0; 5]; - println!("数组 arr = {:?}", arr); + print!("数组 arr = "); + inc::print_util::print_array(&arr); // 在 Rust 中,指定长度时([i32; 5])为数组 // 由于 Rust 的数组被设计为在编译期确定长度,因此只能使用常量来指定长度 // 为了方便实现扩容 extend() 方法,以下将(Vec) 看作数组(Array)也是rust一般情况下使用动态数组的类型 - let nums = vec![1, 3, 2, 5, 4]; - println!("数组 nums = {:?}", nums); + let nums = vec![ 1, 3, 2, 5, 4 ]; + print!("\n数组 nums = "); + inc::print_util::print_array(&nums); /* 随机访问 */ let random_num = random_access(&nums); - println!("在 nums 中获取随机元素 {}", random_num); + println!("\n在 nums 中获取随机元素 {}", random_num); /* 长度扩展 */ let mut nums = extend(nums, 3); - println!("将数组长度扩展至 8 ,得到 nums = {:?}", nums); + print!("将数组长度扩展至 8 ,得到 nums = "); + inc::print_util::print_array(&arr); /* 插入元素 */ insert(&mut nums, 6, 3); - println!("在索引 3 处插入数字 6 ,得到 nums = {:?}", nums); + print!("\n在索引 3 处插入数字 6 ,得到 nums = "); + inc::print_util::print_array(&nums); /* 删除元素 */ remove(&mut nums, 2); - println!("删除索引 2 处的元素,得到 nums = {:?}", nums); + print!("\n删除索引 2 处的元素,得到 nums = "); + inc::print_util::print_array(&nums); /* 遍历数组 */ traverse(&nums); /* 查找元素 */ - let index = find(&nums, 3); - println!("在 nums 中查找元素 3 ,得到索引 = {:?}", index); + let index = find(&nums, 3).unwrap(); + println!("\n在 nums 中查找元素 3 ,得到索引 = {}", index); } \ No newline at end of file diff --git a/codes/rust/chapter_array_and_linkedlist/list.rs b/codes/rust/chapter_array_and_linkedlist/list.rs index b9b3d1ee..46187be9 100644 --- a/codes/rust/chapter_array_and_linkedlist/list.rs +++ b/codes/rust/chapter_array_and_linkedlist/list.rs @@ -1,67 +1,74 @@ /** - * File: array.rs + * File: list.rs * Created Time: 2023-01-18 - * Author: xBLACICEx (xBLACKICEx@outlook.com) + * Author: xBLACICEx (xBLACKICEx@outlook.com), sjinzh (sjinzh@gmail.com) */ -#[allow(unused_variables)] + #[allow(unused_variables)] -/* Driver Code */ -fn main() { - /* 初始化列表 */ - let mut list: Vec = vec![1, 3, 2, 5, 4]; - println!("列表 list = {:?}", list); - - /* 访问元素 */ - let num = list[1]; - println!("访问索引 1 处的元素,得到 num = {num}"); - - /* 更新元素 */ - list[1] = 0; - println!("将索引 1 处的元素更新为 0 ,得到 list = {:?}", list); - - /* 清空列表 */ - list.clear(); - println!("清空列表后 list = {:?}", list); - - /* 尾部添加元素 */ - list.push(1); - list.push(3); - list.push(2); - list.push(5); - list.push(4); - println!("添加元素后 list = {:?}", list); - - /* 中间插入元素 */ - list.insert(3, 6); - println!("在索引 3 处插入数字 6 ,得到 list = {:?}", list); - - /* 删除元素 */ - list.remove(3); - println!("删除索引 3 处的元素,得到 list = {:?}", list); - - /* 通过索引遍历列表 */ - let mut count = 0; - for _ in 0..list.len() { - count += 1; - } - - /* 直接遍历列表元素 */ - count = 0; - for _ in &list { - count += 1; - } // 或者 - // list.iter().for_each(|_| count += 1); - // let count = list.iter().fold(0, |count, _| count + 1); - - /* 拼接两个列表 */ - let mut list1 = vec![6, 8, 7, 10, 9]; - list.append(&mut list1); // append(移动) 之后 list1 为空! - // list.extend(&list1); // extend(借用) list1 能继续使用 - - println!("将列表 list1 拼接到 list 之后,得到 list = {:?}", list); - - /* 排序列表 */ - list.sort(); - println!("排序列表后 list = {:?}", list); -} \ No newline at end of file + /* Driver Code */ + fn main() { + /* 初始化列表 */ + let mut list: Vec = vec![ 1, 3, 2, 5, 4 ]; + print!("列表 list = "); + inc::print_util::print_array(&list); + + /* 访问元素 */ + let num = list[1]; + println!("\n访问索引 1 处的元素,得到 num = {num}"); + + /* 更新元素 */ + list[1] = 0; + print!("将索引 1 处的元素更新为 0 ,得到 list = "); + inc::print_util::print_array(&list); + + /* 清空列表 */ + list.clear(); + print!("\n清空列表后 list = "); + inc::print_util::print_array(&list); + + /* 尾部添加元素 */ + list.push(1); + list.push(3); + list.push(2); + list.push(5); + list.push(4); + print!("\n添加元素后 list = "); + inc::print_util::print_array(&list); + + /* 中间插入元素 */ + list.insert(3, 6); + print!("\n在索引 3 处插入数字 6 ,得到 list = "); + inc::print_util::print_array(&list); + + /* 删除元素 */ + list.remove(3); + print!("\n删除索引 3 处的元素,得到 list = "); + inc::print_util::print_array(&list); + + /* 通过索引遍历列表 */ + let mut count = 0; + for _ in 0..list.len() { + count += 1; + } + + /* 直接遍历列表元素 */ + count = 0; + for _ in &list { + count += 1; + } // 或者 + // list.iter().for_each(|_| count += 1); + // let count = list.iter().fold(0, |count, _| count + 1); + + /* 拼接两个列表 */ + let mut list1 = vec![ 6, 8, 7, 10, 9 ]; + list.append(&mut list1); // append(移动) 之后 list1 为空! + // list.extend(&list1); // extend(借用) list1 能继续使用 + print!("\n将列表 list1 拼接到 list 之后,得到 list = "); + inc::print_util::print_array(&list); + + /* 排序列表 */ + list.sort(); + print!("\n排序列表后 list = "); + inc::print_util::print_array(&list); + } \ No newline at end of file diff --git a/codes/rust/chapter_computational_complexity/Cargo.toml b/codes/rust/chapter_computational_complexity/Cargo.toml deleted file mode 100644 index acfb2170..00000000 --- a/codes/rust/chapter_computational_complexity/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "chapter_computational_complexity" -version = "0.1.0" -edition = "2021" - - -[[bin]] -name = "leetcode_two_sum" -path = "leetcode_two_sum.rs" - -[[bin]] -name = "time_complexity" -path = "time_complexity.rs" - -[[bin]] -name = "worst_best_time_complexity" -path = "worst_best_time_complexity.rs" - - -[dependencies] -rand = "0.8.5" diff --git a/codes/rust/chapter_computational_complexity/leetcode_two_sum.rs b/codes/rust/chapter_computational_complexity/leetcode_two_sum.rs index f44dc714..9b5b036b 100644 --- a/codes/rust/chapter_computational_complexity/leetcode_two_sum.rs +++ b/codes/rust/chapter_computational_complexity/leetcode_two_sum.rs @@ -1,7 +1,7 @@ /** * File: leetcode_two_sum.rs * Created Time: 2023-01-14 - * Author: xBLACICEx (xBLACKICEx@outlook.com) + * Author: xBLACICEx (xBLACKICEx@outlook.com), sjinzh (sjinzh@gmail.com) */ use std::collections::HashMap; @@ -11,8 +11,10 @@ struct SolutionHashMap; /* 方法一:暴力枚举 */ impl SolutionBruteForce { pub fn two_sum(nums: &Vec, target: i32) -> Vec { - for i in 0..nums.len() - 1 { - for j in i + 1..nums.len() { + let size = nums.len(); + // 两层循环,时间复杂度 O(n^2) + for i in 0..size - 1 { + for j in i + 1..size { if nums[i] + nums[j] == target { return vec![i as i32, j as i32]; } @@ -25,28 +27,31 @@ impl SolutionBruteForce { /* 方法二:辅助哈希表 */ impl SolutionHashMap { pub fn two_sum(nums: &Vec, target: i32) -> Vec { - let mut hm = HashMap::new(); - - for (i, n) in nums.iter().enumerate() { - match hm.get(&(target - n)) { + // 辅助哈希表,空间复杂度 O(n) + let mut dic = HashMap::new(); + // 单层循环,时间复杂度 O(n) + for (i, num) in nums.iter().enumerate() { + match dic.get(&(target - num)) { Some(v) => return vec![*v as i32, i as i32], - None => hm.insert(n, i) + None => dic.insert(num, i as i32) }; } vec![] } } -// Driver Code +/* Driver Code */ fn main() { // ======= Test Case ======= - let nums = vec![2,7,11,15]; + let nums = vec![ 2, 7, 11, 15 ]; let target = 9; // 方法一 let res = SolutionBruteForce::two_sum(&nums, target); - println!("方法一 res = {:?}", res); + print!("方法一 res = "); + inc::print_util::print_array(&res); // 方法二 let res = SolutionHashMap::two_sum(&nums, target); - println!("方法二 res = {:?}", res); + print!("\n方法二 res = "); + inc::print_util::print_array(&res); } \ No newline at end of file diff --git a/codes/rust/chapter_computational_complexity/time_complexity.rs b/codes/rust/chapter_computational_complexity/time_complexity.rs index 6ddacc5c..9f24db7c 100644 --- a/codes/rust/chapter_computational_complexity/time_complexity.rs +++ b/codes/rust/chapter_computational_complexity/time_complexity.rs @@ -1,16 +1,16 @@ /** * File: time_complexity.rs * Created Time: 2023-01-10 - * Author: xBLACICEx (xBLACKICEx@outlook.com) + * Author: xBLACICEx (xBLACKICEx@outlook.com), sjinzh (sjinzh@gmail.com) */ -#[allow(unused_variables)] /* 常数阶 */ fn constant(n: i32) -> i32 { + _ = n; let mut count = 0; - let size = 100000; + let size = 100_000; for _ in 0..size { - count += 1 + count += 1; } count } @@ -34,6 +34,7 @@ fn array_traversal(nums: &[i32]) -> i32 { count } +/* 平方阶 */ fn quadratic(n: i32) -> i32 { let mut count = 0; // 循环次数与数组长度成平方关系 @@ -88,30 +89,30 @@ fn exp_recur(n: i32) -> i32 { } /* 对数阶(循环实现) */ -fn logarithmic(mut n: i32) -> i32 { +fn logarithmic(mut n: f32) -> i32 { let mut count = 0; - - while n > 1 { - n = n / 2; + while n > 1.0 { + n = n / 2.0; count += 1; } count } /* 对数阶(递归实现) */ -fn log_recur(n: i32) -> i32 { - if n <= 1 { +fn log_recur(n: f32) -> i32 { + if n <= 1.0 { return 0; } - log_recur(n / 2) + 1 + log_recur(n / 2.0) + 1 } /* 线性对数阶 */ -fn linear_log_recur(n: f64) -> i32 { +fn linear_log_recur(n: f32) -> i32 { if n <= 1.0 { return 1; } - let mut count = linear_log_recur(n / 2.0) + linear_log_recur(n / 2.0); + let mut count = linear_log_recur(n / 2.0) + + linear_log_recur(n / 2.0); for _ in 0 ..n as i32 { count += 1; } @@ -147,7 +148,6 @@ fn main() { count = quadratic(n); println!("平方阶的计算操作数量 = {}", count); - let mut nums = (1..=n).rev().collect::>(); // [n,n-1,...,2,1] count = bubble_sort(&mut nums); println!("平方阶(冒泡排序)的计算操作数量 = {}", count); @@ -157,12 +157,12 @@ fn main() { count = exp_recur(n); println!("指数阶(递归实现)的计算操作数量 = {}", count); - count = logarithmic(n); + count = logarithmic(n as f32); println!("对数阶(循环实现)的计算操作数量 = {}", count); - count = log_recur(n); + count = log_recur(n as f32); println!("对数阶(递归实现)的计算操作数量 = {}", count); - count = linear_log_recur(n.into()); + count = linear_log_recur(n as f32); println!("线性对数阶(递归实现)的计算操作数量 = {}", count); count = factorial_recur(n); diff --git a/codes/rust/chapter_computational_complexity/worst_best_time_complexity.rs b/codes/rust/chapter_computational_complexity/worst_best_time_complexity.rs index c167d023..706b70f5 100644 --- a/codes/rust/chapter_computational_complexity/worst_best_time_complexity.rs +++ b/codes/rust/chapter_computational_complexity/worst_best_time_complexity.rs @@ -1,40 +1,41 @@ /** * File: time_complexity.rs * Created Time: 2023-01-13 - * Author: xBLACICEx (xBLACKICEx@outlook.com) + * Author: xBLACICEx (xBLACKICEx@outlook.com), sjinzh (sjinzh@gmail.com) */ -use rand::seq::SliceRandom; -use rand::thread_rng; - -/* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */ -fn random_numbers(n: i32) -> Vec { - // 生成数组 nums = { 1, 2, 3, ..., n } - let mut nums = (1..n + 1).collect::>(); - // 随机打乱数组元素 - nums.shuffle(&mut thread_rng()); - nums -} - -/* 查找数组 nums 中数字 1 所在索引 */ -fn find_one(nums: &[i32]) -> Option { - for i in 0..nums.len() { - // 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) - // 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) - if nums[i] == 1 { - return Some(i); - } - } - None -} - -/* Driver Code */ -fn main() { - for _ in 0..10 { - let n = 100; - let nums = random_numbers(n); - let index = find_one(&nums); - println!("\n数组 [ 1, 2, ..., n ] 被打乱后 = {:?}", nums); - println!("数字 1 的索引为 {:?}", index); - } -} \ No newline at end of file + use rand::seq::SliceRandom; + use rand::thread_rng; + + /* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */ + fn random_numbers(n: i32) -> Vec { + // 生成数组 nums = { 1, 2, 3, ..., n } + let mut nums = (1..=n).collect::>(); + // 随机打乱数组元素 + nums.shuffle(&mut thread_rng()); + nums + } + + /* 查找数组 nums 中数字 1 所在索引 */ + fn find_one(nums: &[i32]) -> Option { + for i in 0..nums.len() { + // 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) + // 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) + if nums[i] == 1 { + return Some(i); + } + } + None + } + + /* Driver Code */ + fn main() { + for _ in 0..10 { + let n = 100; + let nums = random_numbers(n); + let index = find_one(&nums).unwrap(); + print!("\n数组 [ 1, 2, ..., n ] 被打乱后 = "); + inc::print_util::print_array(&nums); + println!("\n数字 1 的索引为 {}", index); + } + } \ No newline at end of file diff --git a/codes/rust/chapter_hashing/hash_map.rs b/codes/rust/chapter_hashing/hash_map.rs new file mode 100644 index 00000000..562a349d --- /dev/null +++ b/codes/rust/chapter_hashing/hash_map.rs @@ -0,0 +1,46 @@ +/** + * File: hash_map.rs + * Created Time: 2023-02-05 + * Author: sjinzh (sjinzh@gmail.com) +*/ + +use std::collections::HashMap; + +/* Driver Code */ +pub fn main() { + // 初始化哈希表 + let mut map = HashMap::new(); + + // 添加操作 + // 在哈希表中添加键值对 (key, value) + map.insert(12836, "小哈"); + map.insert(15937, "小啰"); + map.insert(16750, "小算"); + map.insert(13276, "小法"); + map.insert(10583, "小鸭"); + println!("\n添加完成后,哈希表为\nKey -> Value"); + inc::print_util::print_hash_map(&map); + + // 查询操作 + // 向哈希表输入键 key ,得到值 value + let name = map.get(&15937).copied().unwrap(); + println!("\n输入学号 15937 ,查询到姓名 {name}"); + + // 删除操作 + // 在哈希表中删除键值对 (key, value) + _ = map.remove(&10583); + println!("\n删除 10583 后,哈希表为\nKey -> Value"); + inc::print_util::print_hash_map(&map); + + // 遍历哈希表 + println!("\n遍历键值对 Key->Value"); + inc::print_util::print_hash_map(&map); + println!("\n单独遍历键 Key"); + for key in map.keys() { + println!("{key}"); + } + println!("\n单独遍历值 value"); + for value in map.values() { + println!("{value}"); + } +} \ No newline at end of file diff --git a/codes/rust/chapter_searching/binary_search.rs b/codes/rust/chapter_searching/binary_search.rs new file mode 100644 index 00000000..1c2edcdb --- /dev/null +++ b/codes/rust/chapter_searching/binary_search.rs @@ -0,0 +1,59 @@ +/** + * File: binary_search.rs + * Created Time: 2023-02-05 + * Author: sjinzh (sjinzh@gmail.com) +*/ + +/* 二分查找(双闭区间) */ +fn binary_search(nums: &[i32], target: i32) -> i32 { + // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 + let mut i = 0; + let mut j = nums.len() - 1; + // 循环,当搜索区间为空时跳出(当 i > j 时为空) + while i <= j { + let m = (i + j) / 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 as i32; + } + } + // 未找到目标元素,返回 -1 + return -1; +} + +/* 二分查找(左闭右开) */ +fn binary_search1(nums: &[i32], target: i32) -> i32 { + // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 + let mut i = 0; + let mut j = nums.len(); + // 循环,当搜索区间为空时跳出(当 i = j 时为空) + while i < j { + let m = (i + j) / 2; // 计算中点索引 m + if nums[m] < target { // 此情况说明 target 在区间 [m+1, j) 中 + i = m + 1; + } else if nums[m] > target { // 此情况说明 target 在区间 [i, m) 中 + j = m - 1; + } else { // 找到目标元素,返回其索引 + return m as i32; + } + } + // 未找到目标元素,返回 -1 + return -1; +} + +/* Driver Code */ +pub fn main() { + let target = 6; + let nums = [ 1, 3, 6, 8, 12, 15, 23, 67, 70, 92 ]; + + /* 二分查找(双闭区间) */ + let mut index = binary_search(&nums, target); + println!("目标元素 6 的索引 = {index}"); + + /* 二分查找(左闭右开) */ + index = binary_search1(&nums, target); + println!("目标元素 6 的索引 = {index}"); +} \ No newline at end of file diff --git a/codes/rust/chapter_sorting/bubble_sort.rs b/codes/rust/chapter_sorting/bubble_sort.rs new file mode 100644 index 00000000..3c8e294e --- /dev/null +++ b/codes/rust/chapter_sorting/bubble_sort.rs @@ -0,0 +1,53 @@ +/** + * File: bubble_sort.rs + * Created Time: 2023-02-05 + * Author: sjinzh (sjinzh@gmail.com) +*/ + +/* 冒泡排序 */ +fn bubble_sort(nums: &mut [i32]) { + // 外循环:待排序元素数量为 n-1, n-2, ..., 1 + for i in (1..nums.len()).rev() { + // 内循环:冒泡操作 + for j in 0..i { + if nums[j] > nums[j + 1] { + // 交换 nums[j] 与 nums[j + 1] + let tmp = nums[j]; + nums[j] = nums[j + 1]; + nums[j + 1] = tmp; + } + } + } +} + +/* 冒泡排序(标志优化) */ +fn bubble_sort_with_flag(nums: &mut [i32]) { + // 外循环:待排序元素数量为 n-1, n-2, ..., 1 + for i in (1..nums.len()).rev() { + let mut flag = false; // 初始化标志位 + // 内循环:冒泡操作 + for j in 0..i { + 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}; // 此轮冒泡未交换任何元素,直接跳出 + } +} + +/* Driver Code */ +pub fn main() { + let mut nums = [ 4, 1, 3, 1, 5, 2 ]; + bubble_sort(&mut nums); + print!("冒泡排序完成后 nums = "); + inc::print_util::print_array(&nums); + + let mut nums1 = [ 4, 1, 3, 1, 5, 2 ]; + bubble_sort_with_flag(&mut nums1); + print!("\n冒泡排序完成后 nums1 = "); + inc::print_util::print_array(&nums1); +} \ No newline at end of file diff --git a/codes/rust/chapter_stack_and_queue/deque.rs b/codes/rust/chapter_stack_and_queue/deque.rs new file mode 100644 index 00000000..6cb12c0f --- /dev/null +++ b/codes/rust/chapter_stack_and_queue/deque.rs @@ -0,0 +1,42 @@ +/** + * File: deque.rs + * Created Time: 2023-02-05 + * Author: sjinzh (sjinzh@gmail.com) +*/ + +use std::collections::LinkedList; + +/* Driver Code */ +pub fn main() { + // 初始化双向队列 + let mut deque: LinkedList = LinkedList::new(); + deque.push_back(2); // 添加至队尾 + deque.push_back(5); + deque.push_back(4); + deque.push_front(3); // 添加至队首 + deque.push_front(1); + print!("双向队列 deque = "); + inc::print_util::print_queue(&deque); + + // 访问元素 + let peek_first = deque.front().unwrap(); // 队首元素 + print!("\n队首元素 peekFirst = {peek_first}"); + let peek_last = deque.back().unwrap(); // 队尾元素 + print!("\n队尾元素 peekLast = {peek_last}"); + + // 元素出队 + let poll_first = deque.pop_front().unwrap(); // 队首元素出队 + print!("\n队首出队元素 pollFirst = {poll_first},队首出队后 deque = "); + inc::print_util::print_queue(&deque); + let poll_last = deque.pop_back().unwrap(); // 队尾元素出队 + print!("\n队尾出队元素 pollLast = {poll_last},队尾出队后 deque = "); + inc::print_util::print_queue(&deque); + + // 获取双向队列的长度 + let size = deque.len(); + print!("\n双向队列长度 size = {size}"); + + /* 判断双向队列是否为空 */ + let is_empty = deque.is_empty(); + print!("\n双向队列是否为空 = {is_empty}"); +} \ No newline at end of file diff --git a/codes/rust/chapter_stack_and_queue/queue.rs b/codes/rust/chapter_stack_and_queue/queue.rs new file mode 100644 index 00000000..54a7597f --- /dev/null +++ b/codes/rust/chapter_stack_and_queue/queue.rs @@ -0,0 +1,39 @@ +/** + * File: queue.rs + * Created Time: 2023-02-05 + * Author: sjinzh (sjinzh@gmail.com) +*/ + +use std::collections::LinkedList; + +/* Driver Code */ +pub fn main() { + // 初始化队列 + let mut queue: LinkedList = LinkedList::new(); + + // 元素入队 + queue.push_back(1); + queue.push_back(3); + queue.push_back(2); + queue.push_back(5); + queue.push_back(4); + print!("队列 queue = "); + inc::print_util::print_queue(&queue); + + // 访问队首元素 + let peek = queue.front().unwrap(); + println!("\n队首元素 peek = {peek}"); + + // 元素出队 + let poll = queue.pop_front().unwrap(); + print!("出队元素 poll = {poll},出队后 queue = "); + inc::print_util::print_queue(&queue); + + // 获取队列的长度 + let size = queue.len(); + print!("\n队列长度 size = {size}"); + + /* 判断队列是否为空 */ + let is_empty = queue.is_empty(); + print!("\n队列是否为空 = {is_empty}"); +} \ No newline at end of file diff --git a/codes/rust/chapter_stack_and_queue/stack.rs b/codes/rust/chapter_stack_and_queue/stack.rs new file mode 100644 index 00000000..520f7b07 --- /dev/null +++ b/codes/rust/chapter_stack_and_queue/stack.rs @@ -0,0 +1,38 @@ +/** + * File: stack.rs + * Created Time: 2023-02-05 + * Author: sjinzh (sjinzh@gmail.com) +*/ + +/* Driver Code */ +pub fn main() { + // 初始化栈 + // 在 rust 中,推荐将 Vec 当作栈来使用 + let mut stack: Vec = Vec::new(); + + // 元素入栈 + stack.push(1); + stack.push(3); + stack.push(2); + stack.push(5); + stack.push(4); + print!("栈 stack = "); + inc::print_util::print_array(&stack); + + // 访问栈顶元素 + let peek = stack.get(stack.len() - 1).unwrap(); + print!("\n栈顶元素 peek = {peek}"); + + // 元素出栈 + let pop = stack.pop().unwrap(); + print!("\n出栈元素 pop = {pop},出栈后 stack = "); + inc::print_util::print_array(&stack); + + // 获取栈的长度 + let size = stack.len(); + print!("\n栈的长度 size = {size}"); + + // 判断栈是否为空 + let is_empty = stack.is_empty(); + print!("\n栈是否为空 = {is_empty}"); +} \ No newline at end of file diff --git a/codes/rust/include/include.rs b/codes/rust/include/include.rs new file mode 100644 index 00000000..2e9cdecf --- /dev/null +++ b/codes/rust/include/include.rs @@ -0,0 +1,7 @@ +/** + * File: include.rs + * Created Time: 2023-02-05 + * Author: sjinzh (sjinzh@gmail.com) +*/ + +pub mod print_util; \ No newline at end of file diff --git a/codes/rust/include/print_util.rs b/codes/rust/include/print_util.rs new file mode 100644 index 00000000..8800fea3 --- /dev/null +++ b/codes/rust/include/print_util.rs @@ -0,0 +1,37 @@ +/** + * File: print_util.rs + * Created Time: 2023-02-05 + * Author: sjinzh (sjinzh@gmail.com) +*/ + +use std::fmt::Display; +use std::collections::HashMap; +use std::collections::LinkedList; + +/* Print an array */ +pub fn print_array(nums: &[T]) { + print!("["); + if nums.len() > 0 { + for (i, num) in nums.iter().enumerate() { + print!("{}{}", num, if i == nums.len() - 1 {"]"} else {", "} ); + } + } else { + print!("]"); + } +} + +/* Print a hash map */ +pub fn print_hash_map(map: &HashMap) { + for (key, value) in map { + println!("{key} -> {value}"); + } +} + +/* Print a queue or deque */ +pub fn print_queue(queue: &LinkedList) { + print!("["); + let iter = queue.iter(); + for (i, data) in iter.enumerate() { + print!("{}{}", data, if i == queue.len() - 1 {"]"} else {", "} ); + } +} \ No newline at end of file diff --git a/codes/zig/chapter_stack_and_queue/deque.zig b/codes/zig/chapter_stack_and_queue/deque.zig index 097ab622..1e617148 100644 --- a/codes/zig/chapter_stack_and_queue/deque.zig +++ b/codes/zig/chapter_stack_and_queue/deque.zig @@ -17,25 +17,25 @@ pub fn main() !void { var node3 = L.Node{ .data = 4 }; var node4 = L.Node{ .data = 3 }; var node5 = L.Node{ .data = 1 }; - deque.append(&node1); + deque.append(&node1); // 添加至队尾 deque.append(&node2); deque.append(&node3); - deque.prepend(&node4); + deque.prepend(&node4); // 添加至队首 deque.prepend(&node5); std.debug.print("双向队列 deque = ", .{}); inc.PrintUtil.printQueue(i32, deque); // 访问元素 - var peekFirst = deque.first.?.data; + var peekFirst = deque.first.?.data; // 队首元素 std.debug.print("\n队首元素 peekFirst = {}", .{peekFirst}); - var peekLast = deque.last.?.data; - std.debug.print("\n队首元素 peekLast = {}", .{peekLast}); + var peekLast = deque.last.?.data; // 队尾元素 + std.debug.print("\n队尾元素 peekLast = {}", .{peekLast}); // 元素出队 - var pollFirst = deque.popFirst().?.data; + var pollFirst = deque.popFirst().?.data; // 队首元素出队 std.debug.print("\n队首出队元素 pollFirst = {},队首出队后 deque = ", .{pollFirst}); inc.PrintUtil.printQueue(i32, deque); - var pollLast = deque.pop().?.data; + var pollLast = deque.pop().?.data; // 队尾元素出队 std.debug.print("\n队尾出队元素 pollLast = {},队尾出队后 deque = ", .{pollLast}); inc.PrintUtil.printQueue(i32, deque); @@ -43,7 +43,7 @@ pub fn main() !void { var size = deque.len; std.debug.print("\n双向队列长度 size = {}", .{size}); - // 判断队列是否为空 + // 判断双向队列是否为空 var isEmpty = if (deque.len == 0) true else false; std.debug.print("\n双向队列是否为空 = {}", .{isEmpty}); diff --git a/codes/zig/chapter_stack_and_queue/queue.zig b/codes/zig/chapter_stack_and_queue/queue.zig index 5d601b6b..011b3618 100644 --- a/codes/zig/chapter_stack_and_queue/queue.zig +++ b/codes/zig/chapter_stack_and_queue/queue.zig @@ -26,12 +26,12 @@ pub fn main() !void { inc.PrintUtil.printQueue(i32, queue); // 访问队首元素 - var front = queue.first.?.data; - std.debug.print("\n队首元素 front = {}", .{front}); + var peek = queue.first.?.data; + std.debug.print("\n队首元素 peek = {}", .{peek}); // 元素出队 - front = queue.popFirst().?.data; - std.debug.print("\n出队元素 front = {},出队后 queue = ", .{front}); + var poll = queue.popFirst().?.data; + std.debug.print("\n出队元素 poll = {},出队后 queue = ", .{poll}); inc.PrintUtil.printQueue(i32, queue); // 获取队列的长度 diff --git a/codes/zig/chapter_stack_and_queue/stack.zig b/codes/zig/chapter_stack_and_queue/stack.zig index 95ed427b..fd1d2b2d 100644 --- a/codes/zig/chapter_stack_and_queue/stack.zig +++ b/codes/zig/chapter_stack_and_queue/stack.zig @@ -23,12 +23,12 @@ pub fn main() !void { inc.PrintUtil.printList(i32, stack); // 访问栈顶元素 - var top = stack.items[stack.items.len - 1]; - std.debug.print("\n栈顶元素 top = {}", .{top}); + var peek = stack.items[stack.items.len - 1]; + std.debug.print("\n栈顶元素 peek = {}", .{peek}); // 元素出栈 - top = stack.pop(); - std.debug.print("\n出栈元素 pop = {},出栈后 stack = ", .{top}); + var pop = stack.pop(); + std.debug.print("\n出栈元素 pop = {},出栈后 stack = ", .{pop}); inc.PrintUtil.printList(i32, stack); // 获取栈的长度