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 <krahets@163.com>
This commit is contained in:
sjinzh 2023-03-12 02:48:44 +08:00 committed by GitHub
parent bbef87ccfe
commit 050b922f8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 282 additions and 2 deletions

View File

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

View File

@ -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<T>(n0: &Rc<RefCell<ListNode<T>>>, P: Rc<RefCell<ListNode<T>>>) {
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<T>(n0: &Rc<RefCell<ListNode<T>>>) {
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<T>(head: Rc<RefCell<ListNode<T>>>, index: i32) -> Rc<RefCell<ListNode<T>>> {
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<T: PartialEq>(head: Rc<RefCell<ListNode<T>>>, 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);
}

View File

@ -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<i32>,
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<i32> {
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());
}

View File

@ -5,4 +5,6 @@
*/
pub mod print_util;
pub mod tree_node;
pub mod tree_node;
pub mod list_node;
pub use list_node::ListNode;

View File

@ -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<T> {
pub val: T,
pub next: Option<Rc<RefCell<ListNode<T>>>>,
}
impl<T> ListNode<T> {
pub fn new(val: T) -> Rc<RefCell<ListNode<T>>> {
Rc::new(RefCell::new(ListNode {
val,
next: None,
}))
}
}

View File

@ -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<T: Display>(queue: &VecDeque<T>) {
print!("{}{}", data, if i == queue.len() - 1 {"]"} else {", "} );
}
}
/* Print a linked list */
pub fn print_linked_list<T: Display>(head: &Rc<RefCell<ListNode<T>>>) {
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<RefCell<TreeNode>>) {
_print_tree(Some(root), None, false);
}

View File

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