From 050b922f8a5da855b68a03815956b35b1fb84ec2 Mon Sep 17 00:00:00 2001 From: sjinzh <99076655+sjinzh@users.noreply.github.com> Date: Sun, 12 Mar 2023 02:48:44 +0800 Subject: [PATCH] feat: add rust codes for linked_list and my_list (#408) * feat: add rust codes for linked_list * feat: add rust codes for my_list * Update linked_list.rs * Update print_util.rs --------- Co-authored-by: Yudong Jin --- codes/rust/Cargo.toml | 10 ++ .../linked_list.rs | 83 ++++++++++ .../chapter_array_and_linkedlist/my_list.rs | 154 ++++++++++++++++++ codes/rust/include/include.rs | 4 +- codes/rust/include/list_node.rs | 22 +++ codes/rust/include/print_util.rs | 10 ++ .../chapter_array_and_linkedlist/my_list.zig | 1 - 7 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 codes/rust/chapter_array_and_linkedlist/linked_list.rs create mode 100644 codes/rust/chapter_array_and_linkedlist/my_list.rs create mode 100644 codes/rust/include/list_node.rs diff --git a/codes/rust/Cargo.toml b/codes/rust/Cargo.toml index b203b74e..396f6818 100644 --- a/codes/rust/Cargo.toml +++ b/codes/rust/Cargo.toml @@ -24,11 +24,21 @@ path = "chapter_computational_complexity/leetcode_two_sum.rs" name = "array" path = "chapter_array_and_linkedlist/array.rs" +# Run Command: cargo run --bin linked_list +[[bin]] +name = "linked_list" +path = "chapter_array_and_linkedlist/linked_list.rs" + # Run Command: cargo run --bin list [[bin]] name = "list" path = "chapter_array_and_linkedlist/list.rs" +# Run Command: cargo run --bin my_list +[[bin]] +name = "my_list" +path = "chapter_array_and_linkedlist/my_list.rs" + # Run Command: cargo run --bin stack [[bin]] name = "stack" diff --git a/codes/rust/chapter_array_and_linkedlist/linked_list.rs b/codes/rust/chapter_array_and_linkedlist/linked_list.rs new file mode 100644 index 00000000..16c14e18 --- /dev/null +++ b/codes/rust/chapter_array_and_linkedlist/linked_list.rs @@ -0,0 +1,83 @@ +/* + * File: linked_list.rs + * Created Time: 2023-03-05 + * Author: sjinzh (sjinzh@gmail.com) + */ + +include!("../include/include.rs"); +use std::rc::Rc; +use std::cell::RefCell; + +/* 在链表的结点 n0 之后插入结点 P */ +#[allow(non_snake_case)] +pub fn insert(n0: &Rc>>, P: Rc>>) { + let n1 = n0.borrow_mut().next.take(); + P.borrow_mut().next = n1; + n0.borrow_mut().next = Some(P); +} + +/* 删除链表的结点 n0 之后的首个结点 */ +#[allow(non_snake_case)] +pub fn remove(n0: &Rc>>) { + if n0.borrow().next.is_none() {return}; + // n0 -> P -> n1 + let P = n0.borrow_mut().next.take(); + if let Some(node) = P { + let n1 = node.borrow_mut().next.take(); + n0.borrow_mut().next = n1; + } + } + +/* 访问链表中索引为 index 的结点 */ +pub fn access(head: Rc>>, index: i32) -> Rc>> { + if index <= 0 {return head}; + if let Some(node) = &head.borrow_mut().next { + return access(node.clone(), index - 1); + } + return head; + } + +/* 在链表中查找值为 target 的首个结点 */ +pub fn find(head: Rc>>, target: T, index: i32) -> i32 { + if head.borrow().val == target {return index}; + if let Some(node) = &head.borrow_mut().next { + return find(node.clone(), target, index + 1); + } + return -1; + } + +/* Driver Code */ +fn main() { + /* 初始化链表 */ + // 初始化各个结点 + let n0 = ListNode::new(1); + let n1 = ListNode::new(3); + let n2 = ListNode::new(2); + let n3 = ListNode::new(5); + let n4 = ListNode::new(4); + // 构建引用指向 + n0.borrow_mut().next = Some(n1.clone()); + 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); + + /* 插入结点 */ + insert(&n0, ListNode::new(0)); + print!("插入结点后的链表为 "); + print_util::print_linked_list(&n0); + + /* 删除结点 */ + remove(&n0); + print!("删除结点后的链表为 "); + print_util::print_linked_list(&n0); + + /* 访问结点 */ + let node = access(n0.clone(), 3); + println!("链表中索引 3 处的结点的值 = {}", node.borrow().val); + + /* 查找结点 */ + let index = find(n0.clone(), 2, 0); + println!("链表中值为 2 的结点的索引 = {}", index); +} diff --git a/codes/rust/chapter_array_and_linkedlist/my_list.rs b/codes/rust/chapter_array_and_linkedlist/my_list.rs new file mode 100644 index 00000000..411f8312 --- /dev/null +++ b/codes/rust/chapter_array_and_linkedlist/my_list.rs @@ -0,0 +1,154 @@ +/* + * File: my_list.rs + * Created Time: 2023-03-11 + * Author: sjinzh (sjinzh@gmail.com) + */ + +include!("../include/include.rs"); + +#[allow(dead_code)] +struct MyList { + nums: Vec, + capacity: usize, + size: usize, + extend_ratio: usize, +} + +#[allow(unused,unused_comparisons)] +impl MyList { + /* 构造方法 */ + pub fn new(capacity: usize) -> Self { + let mut vec = Vec::new(); + vec.resize(capacity, 0); + Self { + nums: vec, + capacity, + size: 0, + extend_ratio: 2, + } + } + + /* 获取列表长度(即当前元素数量)*/ + pub fn size(&self) -> usize { + return self.size; + } + + /* 获取列表容量 */ + pub fn capacity(&self) -> usize { + return self.capacity; + } + + /* 访问元素 */ + pub fn get(&self, index: usize) -> i32 { + // 索引如果越界则抛出异常,下同 + if index < 0 || index >= self.size {panic!("索引越界")}; + return self.nums[index]; + } + + /* 更新元素 */ + pub fn set(&mut self, index: usize, num: i32) { + if index < 0 || index >= self.size {panic!("索引越界")}; + self.nums[index] = num; + } + + /* 尾部添加元素 */ + pub fn add(&mut self, num: i32) { + // 元素数量超出容量时,触发扩容机制 + if self.size == self.capacity() { + self.extend_capacity(); + } + self.nums[self.size] = num; + // 更新元素数量 + self.size += 1; + } + + /* 中间插入元素 */ + pub fn insert(&mut self, index: usize, num: i32) { + if index < 0 || index >= self.size() {panic!("索引越界")}; + // 元素数量超出容量时,触发扩容机制 + if self.size == self.capacity() { + self.extend_capacity(); + } + // 将索引 index 以及之后的元素都向后移动一位 + for j in (index..self.size).rev() { + self.nums[j + 1] = self.nums[j]; + } + self.nums[index] = num; + // 更新元素数量 + self.size += 1; + } + + /* 删除元素 */ + pub fn remove(&mut self, index: usize) -> i32 { + if index < 0 || index >= self.size() {panic!("索引越界")}; + let num = self.nums[index]; + // 将索引 index 之后的元素都向前移动一位 + for j in (index..self.size - 1) { + self.nums[j] = self.nums[j + 1]; + } + // 更新元素数量 + self.size -= 1; + // 返回被删除元素 + return num; + } + + /* 列表扩容 */ + pub fn extend_capacity(&mut self) { + let new_capacity = self.capacity * self.extend_ratio; + self.nums.resize(new_capacity, 0); + // 更新列表容量 + self.capacity = new_capacity; + } + + /* 将列表转换为数组 */ + pub fn to_array(&mut self) -> Vec { + let mut nums = Vec::new(); + for i in 0..self.size { + nums.push(self.get(i)); + } + nums + } +} + +/* Driver Code */ +fn main() { + /* 初始化列表 */ + let mut list = MyList::new(10); + /* 尾部添加元素 */ + list.add(1); + list.add(3); + list.add(2); + list.add(5); + list.add(4); + print!("列表 list = "); + print_util::print_array(&list.to_array()); + print!(" ,容量 = {} ,长度 = {}", list.capacity(), list.size()); + + /* 中间插入元素 */ + list.insert(3, 6); + print!("\n在索引 3 处插入数字 6 ,得到 list = "); + print_util::print_array(&list.to_array()); + + /* 删除元素 */ + list.remove(3); + print!("\n删除索引 3 处的元素,得到 list = "); + print_util::print_array(&list.to_array()); + + /* 访问元素 */ + let num = list.get(1); + println!("\n访问索引 1 处的元素,得到 num = {num}"); + + /* 更新元素 */ + list.set(1, 0); + print!("将索引 1 处的元素更新为 0 ,得到 list = "); + print_util::print_array(&list.to_array()); + + /* 测试扩容机制 */ + for i in 0..10 { + // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制 + list.add(i); + } + print!("\n扩容后的列表 list = "); + print_util::print_array(&list.to_array()); + print!(" ,容量 = {} ,长度 = {}", list.capacity(), list.size()); +} \ No newline at end of file diff --git a/codes/rust/include/include.rs b/codes/rust/include/include.rs index 90c6b0e6..8fadec40 100644 --- a/codes/rust/include/include.rs +++ b/codes/rust/include/include.rs @@ -5,4 +5,6 @@ */ pub mod print_util; -pub mod tree_node; \ No newline at end of file +pub mod tree_node; +pub mod list_node; +pub use list_node::ListNode; \ No newline at end of file diff --git a/codes/rust/include/list_node.rs b/codes/rust/include/list_node.rs new file mode 100644 index 00000000..416b3972 --- /dev/null +++ b/codes/rust/include/list_node.rs @@ -0,0 +1,22 @@ +/* + * File: list_node.rs + * Created Time: 2023-03-05 + * Author: sjinzh (sjinzh@gmail.com) + */ + +use std::rc::Rc; +use std::cell::RefCell; + +pub struct ListNode { + pub val: T, + pub next: Option>>>, +} + +impl ListNode { + pub fn new(val: T) -> Rc>> { + Rc::new(RefCell::new(ListNode { + val, + next: None, + })) + } +} diff --git a/codes/rust/include/print_util.rs b/codes/rust/include/print_util.rs index 3511709f..0f11cdac 100644 --- a/codes/rust/include/print_util.rs +++ b/codes/rust/include/print_util.rs @@ -9,6 +9,7 @@ use std::fmt::Display; use std::collections::{HashMap, VecDeque}; use std::rc::Rc; +use crate::list_node::ListNode; use crate::tree_node::TreeNode; struct Trunk<'a, 'b> { @@ -43,6 +44,15 @@ pub fn print_queue(queue: &VecDeque) { print!("{}{}", data, if i == queue.len() - 1 {"]"} else {", "} ); } } + +/* Print a linked list */ +pub fn print_linked_list(head: &Rc>>) { + print!("{}{}", head.borrow().val, if head.borrow().next.is_none() {"\n"} else {" -> "}); + if let Some(node) = &head.borrow().next { + return print_linked_list(node); + } +} + pub fn print_tree(root: &Rc>) { _print_tree(Some(root), None, false); } diff --git a/codes/zig/chapter_array_and_linkedlist/my_list.zig b/codes/zig/chapter_array_and_linkedlist/my_list.zig index 75cef2ac..da6a638d 100644 --- a/codes/zig/chapter_array_and_linkedlist/my_list.zig +++ b/codes/zig/chapter_array_and_linkedlist/my_list.zig @@ -160,7 +160,6 @@ pub fn main() !void { inc.PrintUtil.printArray(i32, try list.toArray()); // 测试扩容机制 - list.set(1, 0); var i: i32 = 0; while (i < 10) : (i += 1) { // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制