mirror of
https://github.com/krahets/hello-algo.git
synced 2025-02-02 22:43:50 +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:
parent
bbef87ccfe
commit
050b922f8a
@ -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());
|
||||||
|
}
|
@ -5,4 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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 时,列表长度将超出列表容量,此时触发扩容机制
|
||||||
|
Loading…
Reference in New Issue
Block a user