mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 22:28:40 +08:00 
			
		
		
		
	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:
		@ -24,11 +24,21 @@ path = "chapter_computational_complexity/leetcode_two_sum.rs"
 | 
				
			|||||||
name = "array"
 | 
					name = "array"
 | 
				
			||||||
path = "chapter_array_and_linkedlist/array.rs"
 | 
					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
 | 
					# Run Command: cargo run --bin list
 | 
				
			||||||
[[bin]]
 | 
					[[bin]]
 | 
				
			||||||
name = "list"
 | 
					name = "list"
 | 
				
			||||||
path = "chapter_array_and_linkedlist/list.rs"
 | 
					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
 | 
					# Run Command: cargo run --bin stack
 | 
				
			||||||
[[bin]]
 | 
					[[bin]]
 | 
				
			||||||
name = "stack"
 | 
					name = "stack"
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										83
									
								
								codes/rust/chapter_array_and_linkedlist/linked_list.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								codes/rust/chapter_array_and_linkedlist/linked_list.rs
									
									
									
									
									
										Normal 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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										154
									
								
								codes/rust/chapter_array_and_linkedlist/my_list.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								codes/rust/chapter_array_and_linkedlist/my_list.rs
									
									
									
									
									
										Normal 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());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -6,3 +6,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub mod print_util;
 | 
					pub mod print_util;
 | 
				
			||||||
pub mod tree_node;
 | 
					pub mod tree_node;
 | 
				
			||||||
 | 
					pub mod list_node;
 | 
				
			||||||
 | 
					pub use list_node::ListNode;
 | 
				
			||||||
							
								
								
									
										22
									
								
								codes/rust/include/list_node.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								codes/rust/include/list_node.rs
									
									
									
									
									
										Normal 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,
 | 
				
			||||||
 | 
					        }))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -9,6 +9,7 @@ use std::fmt::Display;
 | 
				
			|||||||
use std::collections::{HashMap, VecDeque};
 | 
					use std::collections::{HashMap, VecDeque};
 | 
				
			||||||
use std::rc::Rc;
 | 
					use std::rc::Rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::list_node::ListNode;
 | 
				
			||||||
use crate::tree_node::TreeNode;
 | 
					use crate::tree_node::TreeNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Trunk<'a, 'b> {
 | 
					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!("{}{}", 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>>) {
 | 
					pub fn print_tree(root: &Rc<RefCell<TreeNode>>) {
 | 
				
			||||||
    _print_tree(Some(root), None, false);
 | 
					    _print_tree(Some(root), None, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -160,7 +160,6 @@ pub fn main() !void {
 | 
				
			|||||||
    inc.PrintUtil.printArray(i32, try list.toArray());
 | 
					    inc.PrintUtil.printArray(i32, try list.toArray());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 测试扩容机制
 | 
					    // 测试扩容机制
 | 
				
			||||||
    list.set(1, 0);
 | 
					 | 
				
			||||||
    var i: i32 = 0;
 | 
					    var i: i32 = 0;
 | 
				
			||||||
    while (i < 10) : (i += 1) {
 | 
					    while (i < 10) : (i += 1) {
 | 
				
			||||||
        // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制
 | 
					        // 在 i = 5 时,列表长度将超出列表容量,此时触发扩容机制
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user