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
This commit is contained in:
sjinzh 2023-02-05 16:25:42 +08:00 committed by GitHub
parent 93ca29ca6d
commit 8a388d8422
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 559 additions and 280 deletions

View File

@ -1,3 +1,2 @@
**/target target/
**/worst_best_time_complexity/ Cargo.lock
**/time_complexity/

82
codes/rust/Cargo.lock generated
View File

@ -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"

View File

@ -1,6 +1,66 @@
[package]
name = "hello-algo-rust"
version = "0.1.0"
edition = "2021"
[workspace] [lib]
members = [ name = "inc"
"chapter_computational_complexity", path = "include/include.rs"
"chapter_array_and_linkedlist"
] # 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"

View File

@ -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"

View File

@ -1,7 +1,7 @@
/** /**
* File: array.rs * File: array.rs
* Created Time: 2023-01-15 * 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<i32>, enlarge: usize) -> Vec<i32> { fn extend(nums: Vec<i32>, enlarge: usize) -> Vec<i32> {
// 创建一个长度为 nums.len() + enlarge 的新 Vec // 初始化一个扩展长度后的数组
let mut res: Vec<i32> = vec![0; nums.len() + enlarge]; let mut res: Vec<i32> = vec![0; nums.len() + enlarge];
// 将原数组中的所有元素复制到新 // 将原数组中的所有元素复制到新
for i in 0..nums.len() { for i in 0..nums.len() {
@ -70,33 +70,38 @@ fn find(nums: &[i32], target: i32) -> Option<usize> {
/* Driver Code */ /* Driver Code */
fn main() { fn main() {
let arr = [0; 5]; let arr = [0; 5];
println!("数组 arr = {:?}", arr); print!("数组 arr = ");
inc::print_util::print_array(&arr);
// 在 Rust 中,指定长度时([i32; 5])为数组 // 在 Rust 中,指定长度时([i32; 5])为数组
// 由于 Rust 的数组被设计为在编译期确定长度,因此只能使用常量来指定长度 // 由于 Rust 的数组被设计为在编译期确定长度,因此只能使用常量来指定长度
// 为了方便实现扩容 extend() 方法,以下将(Vec) 看作数组Array也是rust一般情况下使用动态数组的类型 // 为了方便实现扩容 extend() 方法,以下将(Vec) 看作数组Array也是rust一般情况下使用动态数组的类型
let nums = vec![1, 3, 2, 5, 4]; let nums = vec![ 1, 3, 2, 5, 4 ];
println!("数组 nums = {:?}", nums); print!("\n数组 nums = ");
inc::print_util::print_array(&nums);
/* 随机访问 */ /* 随机访问 */
let random_num = random_access(&nums); let random_num = random_access(&nums);
println!("在 nums 中获取随机元素 {}", random_num); println!("\n在 nums 中获取随机元素 {}", random_num);
/* 长度扩展 */ /* 长度扩展 */
let mut nums = extend(nums, 3); let mut nums = extend(nums, 3);
println!("将数组长度扩展至 8 ,得到 nums = {:?}", nums); print!("将数组长度扩展至 8 ,得到 nums = ");
inc::print_util::print_array(&arr);
/* 插入元素 */ /* 插入元素 */
insert(&mut nums, 6, 3); 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); remove(&mut nums, 2);
println!("删除索引 2 处的元素,得到 nums = {:?}", nums); print!("\n删除索引 2 处的元素,得到 nums = ");
inc::print_util::print_array(&nums);
/* 遍历数组 */ /* 遍历数组 */
traverse(&nums); traverse(&nums);
/* 查找元素 */ /* 查找元素 */
let index = find(&nums, 3); let index = find(&nums, 3).unwrap();
println!("在 nums 中查找元素 3 ,得到索引 = {:?}", index); println!("\n在 nums 中查找元素 3 ,得到索引 = {}", index);
} }

View File

@ -1,67 +1,74 @@
/** /**
* File: array.rs * File: list.rs
* Created Time: 2023-01-18 * 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 */ /* Driver Code */
fn main() { fn main() {
/* 初始化列表 */ /* 初始化列表 */
let mut list: Vec<i32> = vec![1, 3, 2, 5, 4]; let mut list: Vec<i32> = vec![ 1, 3, 2, 5, 4 ];
println!("列表 list = {:?}", list); print!("列表 list = ");
inc::print_util::print_array(&list);
/* 访问元素 */
let num = list[1]; /* 访问元素 */
println!("访问索引 1 处的元素,得到 num = {num}"); let num = list[1];
println!("\n访问索引 1 处的元素,得到 num = {num}");
/* 更新元素 */
list[1] = 0; /* 更新元素 */
println!("将索引 1 处的元素更新为 0 ,得到 list = {:?}", list); list[1] = 0;
print!("将索引 1 处的元素更新为 0 ,得到 list = ");
/* 清空列表 */ inc::print_util::print_array(&list);
list.clear();
println!("清空列表后 list = {:?}", list); /* 清空列表 */
list.clear();
/* 尾部添加元素 */ print!("\n清空列表后 list = ");
list.push(1); inc::print_util::print_array(&list);
list.push(3);
list.push(2); /* 尾部添加元素 */
list.push(5); list.push(1);
list.push(4); list.push(3);
println!("添加元素后 list = {:?}", list); list.push(2);
list.push(5);
/* 中间插入元素 */ list.push(4);
list.insert(3, 6); print!("\n添加元素后 list = ");
println!("在索引 3 处插入数字 6 ,得到 list = {:?}", list); inc::print_util::print_array(&list);
/* 删除元素 */ /* 中间插入元素 */
list.remove(3); list.insert(3, 6);
println!("删除索引 3 处的元素,得到 list = {:?}", list); print!("\n在索引 3 处插入数字 6 ,得到 list = ");
inc::print_util::print_array(&list);
/* 通过索引遍历列表 */
let mut count = 0; /* 删除元素 */
for _ in 0..list.len() { list.remove(3);
count += 1; print!("\n删除索引 3 处的元素,得到 list = ");
} inc::print_util::print_array(&list);
/* 直接遍历列表元素 */ /* 通过索引遍历列表 */
count = 0; let mut count = 0;
for _ in &list { for _ in 0..list.len() {
count += 1; count += 1;
} // 或者 }
// list.iter().for_each(|_| count += 1);
// let count = list.iter().fold(0, |count, _| count + 1); /* 直接遍历列表元素 */
count = 0;
/* 拼接两个列表 */ for _ in &list {
let mut list1 = vec![6, 8, 7, 10, 9]; count += 1;
list.append(&mut list1); // append移动 之后 list1 为空! } // 或者
// list.extend(&list1); // extend借用 list1 能继续使用 // list.iter().for_each(|_| count += 1);
// let count = list.iter().fold(0, |count, _| count + 1);
println!("将列表 list1 拼接到 list 之后,得到 list = {:?}", list);
/* 拼接两个列表 */
/* 排序列表 */ let mut list1 = vec![ 6, 8, 7, 10, 9 ];
list.sort(); list.append(&mut list1); // append移动 之后 list1 为空!
println!("排序列表后 list = {:?}", list); // 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);
}

View File

@ -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"

View File

@ -1,7 +1,7 @@
/** /**
* File: leetcode_two_sum.rs * File: leetcode_two_sum.rs
* Created Time: 2023-01-14 * Created Time: 2023-01-14
* Author: xBLACICEx (xBLACKICEx@outlook.com) * Author: xBLACICEx (xBLACKICEx@outlook.com), sjinzh (sjinzh@gmail.com)
*/ */
use std::collections::HashMap; use std::collections::HashMap;
@ -11,8 +11,10 @@ struct SolutionHashMap;
/* 方法一:暴力枚举 */ /* 方法一:暴力枚举 */
impl SolutionBruteForce { impl SolutionBruteForce {
pub fn two_sum(nums: &Vec<i32>, target: i32) -> Vec<i32> { pub fn two_sum(nums: &Vec<i32>, target: i32) -> Vec<i32> {
for i in 0..nums.len() - 1 { let size = nums.len();
for j in i + 1..nums.len() { // 两层循环,时间复杂度 O(n^2)
for i in 0..size - 1 {
for j in i + 1..size {
if nums[i] + nums[j] == target { if nums[i] + nums[j] == target {
return vec![i as i32, j as i32]; return vec![i as i32, j as i32];
} }
@ -25,28 +27,31 @@ impl SolutionBruteForce {
/* 方法二:辅助哈希表 */ /* 方法二:辅助哈希表 */
impl SolutionHashMap { impl SolutionHashMap {
pub fn two_sum(nums: &Vec<i32>, target: i32) -> Vec<i32> { pub fn two_sum(nums: &Vec<i32>, target: i32) -> Vec<i32> {
let mut hm = HashMap::new(); // 辅助哈希表,空间复杂度 O(n)
let mut dic = HashMap::new();
for (i, n) in nums.iter().enumerate() { // 单层循环,时间复杂度 O(n)
match hm.get(&(target - n)) { for (i, num) in nums.iter().enumerate() {
match dic.get(&(target - num)) {
Some(v) => return vec![*v as i32, i as i32], Some(v) => return vec![*v as i32, i as i32],
None => hm.insert(n, i) None => dic.insert(num, i as i32)
}; };
} }
vec![] vec![]
} }
} }
// Driver Code /* Driver Code */
fn main() { fn main() {
// ======= Test Case ======= // ======= Test Case =======
let nums = vec![2,7,11,15]; let nums = vec![ 2, 7, 11, 15 ];
let target = 9; let target = 9;
// 方法一 // 方法一
let res = SolutionBruteForce::two_sum(&nums, target); 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); let res = SolutionHashMap::two_sum(&nums, target);
println!("方法二 res = {:?}", res); print!("\n方法二 res = ");
inc::print_util::print_array(&res);
} }

View File

@ -1,16 +1,16 @@
/** /**
* File: time_complexity.rs * File: time_complexity.rs
* Created Time: 2023-01-10 * 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 { fn constant(n: i32) -> i32 {
_ = n;
let mut count = 0; let mut count = 0;
let size = 100000; let size = 100_000;
for _ in 0..size { for _ in 0..size {
count += 1 count += 1;
} }
count count
} }
@ -34,6 +34,7 @@ fn array_traversal(nums: &[i32]) -> i32 {
count count
} }
/* 平方阶 */
fn quadratic(n: i32) -> i32 { fn quadratic(n: i32) -> i32 {
let mut count = 0; 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; let mut count = 0;
while n > 1.0 {
while n > 1 { n = n / 2.0;
n = n / 2;
count += 1; count += 1;
} }
count count
} }
/* 对数阶(递归实现) */ /* 对数阶(递归实现) */
fn log_recur(n: i32) -> i32 { fn log_recur(n: f32) -> i32 {
if n <= 1 { if n <= 1.0 {
return 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 { if n <= 1.0 {
return 1; 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 { for _ in 0 ..n as i32 {
count += 1; count += 1;
} }
@ -147,7 +148,6 @@ fn main() {
count = quadratic(n); count = quadratic(n);
println!("平方阶的计算操作数量 = {}", count); println!("平方阶的计算操作数量 = {}", count);
let mut nums = (1..=n).rev().collect::<Vec<_>>(); // [n,n-1,...,2,1] let mut nums = (1..=n).rev().collect::<Vec<_>>(); // [n,n-1,...,2,1]
count = bubble_sort(&mut nums); count = bubble_sort(&mut nums);
println!("平方阶(冒泡排序)的计算操作数量 = {}", count); println!("平方阶(冒泡排序)的计算操作数量 = {}", count);
@ -157,12 +157,12 @@ fn main() {
count = exp_recur(n); count = exp_recur(n);
println!("指数阶(递归实现)的计算操作数量 = {}", count); println!("指数阶(递归实现)的计算操作数量 = {}", count);
count = logarithmic(n); count = logarithmic(n as f32);
println!("对数阶(循环实现)的计算操作数量 = {}", count); println!("对数阶(循环实现)的计算操作数量 = {}", count);
count = log_recur(n); count = log_recur(n as f32);
println!("对数阶(递归实现)的计算操作数量 = {}", count); println!("对数阶(递归实现)的计算操作数量 = {}", count);
count = linear_log_recur(n.into()); count = linear_log_recur(n as f32);
println!("线性对数阶(递归实现)的计算操作数量 = {}", count); println!("线性对数阶(递归实现)的计算操作数量 = {}", count);
count = factorial_recur(n); count = factorial_recur(n);

View File

@ -1,40 +1,41 @@
/** /**
* File: time_complexity.rs * File: time_complexity.rs
* Created Time: 2023-01-13 * 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::seq::SliceRandom;
use rand::thread_rng; use rand::thread_rng;
/* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */ /* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */
fn random_numbers(n: i32) -> Vec<i32> { fn random_numbers(n: i32) -> Vec<i32> {
// 生成数组 nums = { 1, 2, 3, ..., n } // 生成数组 nums = { 1, 2, 3, ..., n }
let mut nums = (1..n + 1).collect::<Vec<i32>>(); let mut nums = (1..=n).collect::<Vec<i32>>();
// 随机打乱数组元素 // 随机打乱数组元素
nums.shuffle(&mut thread_rng()); nums.shuffle(&mut thread_rng());
nums nums
} }
/* 查找数组 nums 中数字 1 所在索引 */ /* 查找数组 nums 中数字 1 所在索引 */
fn find_one(nums: &[i32]) -> Option<usize> { fn find_one(nums: &[i32]) -> Option<usize> {
for i in 0..nums.len() { for i in 0..nums.len() {
// 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) // 当元素 1 在数组头部时,达到最佳时间复杂度 O(1)
// 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) // 当元素 1 在数组尾部时,达到最差时间复杂度 O(n)
if nums[i] == 1 { if nums[i] == 1 {
return Some(i); return Some(i);
} }
} }
None None
} }
/* Driver Code */ /* Driver Code */
fn main() { fn main() {
for _ in 0..10 { for _ in 0..10 {
let n = 100; let n = 100;
let nums = random_numbers(n); let nums = random_numbers(n);
let index = find_one(&nums); let index = find_one(&nums).unwrap();
println!("\n数组 [ 1, 2, ..., n ] 被打乱后 = {:?}", nums); print!("\n数组 [ 1, 2, ..., n ] 被打乱后 = ");
println!("数字 1 的索引为 {:?}", index); inc::print_util::print_array(&nums);
} println!("\n数字 1 的索引为 {}", index);
} }
}

View File

@ -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}");
}
}

View File

@ -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}");
}

View File

@ -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);
}

View File

@ -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<i32> = 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}");
}

View File

@ -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<i32> = 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}");
}

View File

@ -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<i32> = 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}");
}

View File

@ -0,0 +1,7 @@
/**
* File: include.rs
* Created Time: 2023-02-05
* Author: sjinzh (sjinzh@gmail.com)
*/
pub mod print_util;

View File

@ -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<T: Display>(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<TKey: Display, TValue: Display>(map: &HashMap<TKey, TValue>) {
for (key, value) in map {
println!("{key} -> {value}");
}
}
/* Print a queue or deque */
pub fn print_queue<T: Display>(queue: &LinkedList<T>) {
print!("[");
let iter = queue.iter();
for (i, data) in iter.enumerate() {
print!("{}{}", data, if i == queue.len() - 1 {"]"} else {", "} );
}
}

View File

@ -17,25 +17,25 @@ pub fn main() !void {
var node3 = L.Node{ .data = 4 }; var node3 = L.Node{ .data = 4 };
var node4 = L.Node{ .data = 3 }; var node4 = L.Node{ .data = 3 };
var node5 = L.Node{ .data = 1 }; var node5 = L.Node{ .data = 1 };
deque.append(&node1); deque.append(&node1); //
deque.append(&node2); deque.append(&node2);
deque.append(&node3); deque.append(&node3);
deque.prepend(&node4); deque.prepend(&node4); //
deque.prepend(&node5); deque.prepend(&node5);
std.debug.print("双向队列 deque = ", .{}); std.debug.print("双向队列 deque = ", .{});
inc.PrintUtil.printQueue(i32, deque); inc.PrintUtil.printQueue(i32, deque);
// 访 // 访
var peekFirst = deque.first.?.data; var peekFirst = deque.first.?.data; //
std.debug.print("\n队首元素 peekFirst = {}", .{peekFirst}); std.debug.print("\n队首元素 peekFirst = {}", .{peekFirst});
var peekLast = deque.last.?.data; var peekLast = deque.last.?.data; //
std.debug.print("\n元素 peekLast = {}", .{peekLast}); std.debug.print("\n元素 peekLast = {}", .{peekLast});
// //
var pollFirst = deque.popFirst().?.data; var pollFirst = deque.popFirst().?.data; //
std.debug.print("\n队首出队元素 pollFirst = {},队首出队后 deque = ", .{pollFirst}); std.debug.print("\n队首出队元素 pollFirst = {},队首出队后 deque = ", .{pollFirst});
inc.PrintUtil.printQueue(i32, deque); inc.PrintUtil.printQueue(i32, deque);
var pollLast = deque.pop().?.data; var pollLast = deque.pop().?.data; //
std.debug.print("\n队尾出队元素 pollLast = {},队尾出队后 deque = ", .{pollLast}); std.debug.print("\n队尾出队元素 pollLast = {},队尾出队后 deque = ", .{pollLast});
inc.PrintUtil.printQueue(i32, deque); inc.PrintUtil.printQueue(i32, deque);
@ -43,7 +43,7 @@ pub fn main() !void {
var size = deque.len; var size = deque.len;
std.debug.print("\n双向队列长度 size = {}", .{size}); std.debug.print("\n双向队列长度 size = {}", .{size});
// //
var isEmpty = if (deque.len == 0) true else false; var isEmpty = if (deque.len == 0) true else false;
std.debug.print("\n双向队列是否为空 = {}", .{isEmpty}); std.debug.print("\n双向队列是否为空 = {}", .{isEmpty});

View File

@ -26,12 +26,12 @@ pub fn main() !void {
inc.PrintUtil.printQueue(i32, queue); inc.PrintUtil.printQueue(i32, queue);
// 访 // 访
var front = queue.first.?.data; var peek = queue.first.?.data;
std.debug.print("\n队首元素 front = {}", .{front}); std.debug.print("\n队首元素 peek = {}", .{peek});
// //
front = queue.popFirst().?.data; var poll = queue.popFirst().?.data;
std.debug.print("\n出队元素 front = {},出队后 queue = ", .{front}); std.debug.print("\n出队元素 poll = {},出队后 queue = ", .{poll});
inc.PrintUtil.printQueue(i32, queue); inc.PrintUtil.printQueue(i32, queue);
// //

View File

@ -23,12 +23,12 @@ pub fn main() !void {
inc.PrintUtil.printList(i32, stack); inc.PrintUtil.printList(i32, stack);
// 访 // 访
var top = stack.items[stack.items.len - 1]; var peek = stack.items[stack.items.len - 1];
std.debug.print("\n栈顶元素 top = {}", .{top}); std.debug.print("\n栈顶元素 peek = {}", .{peek});
// //
top = stack.pop(); var pop = stack.pop();
std.debug.print("\n出栈元素 pop = {},出栈后 stack = ", .{top}); std.debug.print("\n出栈元素 pop = {},出栈后 stack = ", .{pop});
inc.PrintUtil.printList(i32, stack); inc.PrintUtil.printList(i32, stack);
// //