Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 73 additions & 25 deletions exercises/algorithm/algorithm1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,49 @@
single linked list merge
This problem requires you to merge two ordered singly linked lists into one ordered singly linked list
*/
// I AM NOT DONE


/*
single linked list merge
This problem requires you to merge two ordered singly linked lists into one ordered singly linked list
*/

use std::fmt::{self, Display, Formatter};
use std::ptr::NonNull;
use std::vec::*;

#[derive(Debug)]
struct Node<T> {
val: T,
next: Option<NonNull<Node<T>>>,
val: T, // 节点的值
next: Option<NonNull<Node<T>>>, // 指向下一个节点的指针
}

impl<T> Node<T> {
// 创建新的节点
fn new(t: T) -> Node<T> {
Node {
val: t,
next: None,
}
}
}

#[derive(Debug)]
struct LinkedList<T> {
length: u32,
start: Option<NonNull<Node<T>>>,
end: Option<NonNull<Node<T>>>,
length: u32, // 链表的长度
start: Option<NonNull<Node<T>>>, // 链表的起始节点
end: Option<NonNull<Node<T>>>, // 链表的末尾节点
}

impl<T> Default for LinkedList<T> {
// 默认实现,用于创建一个空链表
fn default() -> Self {
Self::new()
}
}

impl<T> LinkedList<T> {
// 创建新的空链表
pub fn new() -> Self {
Self {
length: 0,
Expand All @@ -44,50 +53,89 @@ impl<T> LinkedList<T> {
}
}

// 向链表中添加一个新元素
pub fn add(&mut self, obj: T) {
let mut node = Box::new(Node::new(obj));
node.next = None;
let node_ptr = Some(unsafe { NonNull::new_unchecked(Box::into_raw(node)) });
match self.end {
None => self.start = node_ptr,
Some(end_ptr) => unsafe { (*end_ptr.as_ptr()).next = node_ptr },
None => self.start = node_ptr, // 如果链表为空,将新节点设置为起始节点
Some(end_ptr) => unsafe { (*end_ptr.as_ptr()).next = node_ptr }, // 将新节点添加到末尾
}
self.end = node_ptr;
self.length += 1;
self.end = node_ptr; // 更新末尾节点指针
self.length += 1; // 增加链表长度
}

// 获取指定索引的元素
pub fn get(&mut self, index: i32) -> Option<&T> {
self.get_ith_node(self.start, index)
}

// 递归查找指定索引的节点
fn get_ith_node(&mut self, node: Option<NonNull<Node<T>>>, index: i32) -> Option<&T> {
match node {
None => None,
Some(next_ptr) => match index {
0 => Some(unsafe { &(*next_ptr.as_ptr()).val }),
_ => self.get_ith_node(unsafe { (*next_ptr.as_ptr()).next }, index - 1),
0 => Some(unsafe { &(*next_ptr.as_ptr()).val }), // 找到节点,返回值
_ => self.get_ith_node(unsafe { (*next_ptr.as_ptr()).next }, index - 1), // 递归查找下一个节点
},
}
}
pub fn merge(list_a:LinkedList<T>,list_b:LinkedList<T>) -> Self
{
//TODO
Self {
length: 0,
start: None,
end: None,

// 合并两个有序链表
pub fn merge(list_a: LinkedList<T>, list_b: LinkedList<T>) -> Self
where
T: PartialOrd + Clone, // 确保 T 实现了 PartialOrd 和 Clone 特征, // 确保 T 实现了 PartialOrd 特征,以支持比较操作
{
let mut merged_list = LinkedList::new(); // 新建合并链表
// 初始化指针,指向两个输入链表的起始节点
let mut current_a = list_a.start;
let mut current_b = list_b.start;

// 遍历两个链表,直到其中一个链表为空
while current_a.is_some() && current_b.is_some() {
// 获取当前节点的值,使用引用借用
let value_a = unsafe { &(*current_a.unwrap().as_ptr()).val };
let value_b = unsafe { &(*current_b.unwrap().as_ptr()).val };

// 比较两个节点的值,将较小的值添加到合并链表
if value_a <= value_b {
merged_list.add(value_a.clone()); // 克隆 value_a 添加到合并链表
current_a = unsafe { (*current_a.unwrap().as_ptr()).next }; // 移动到 list_a 的下一个节点
} else {
merged_list.add(value_b.clone()); // 克隆 value_b 添加到合并链表
current_b = unsafe { (*current_b.unwrap().as_ptr()).next }; // 移动到 list_b 的下一个节点
}
}
}

// 如果 list_a 还有剩余元素,将其添加到合并链表
while current_a.is_some() {
let value_a = unsafe { &(*current_a.unwrap().as_ptr()).val };
merged_list.add(value_a.clone()); // 克隆 value_a 添加到合并链表
current_a = unsafe { (*current_a.unwrap().as_ptr()).next }; // 移动到下一个节点
}

// 如果 list_b 还有剩余元素,将其添加到合并链表
while current_b.is_some() {
let value_b = unsafe { &(*current_b.unwrap().as_ptr()).val };
merged_list.add(value_b.clone()); // 克隆 value_b 添加到合并链表
current_b = unsafe { (*current_b.unwrap().as_ptr()).next }; // 移动到下一个节点
}

// 返回合并后的链表
merged_list
}
}

impl<T> Display for LinkedList<T>
where
T: Display,
{
// 实现 Display trait,用于格式化输出链表
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.start {
Some(node) => write!(f, "{}", unsafe { node.as_ref() }),
None => Ok(()),
Some(node) => write!(f, "{}", unsafe { node.as_ref() }), // 输出链表的起始节点
None => Ok(()), // 空链表
}
}
}
Expand All @@ -96,14 +144,14 @@ impl<T> Display for Node<T>
where
T: Display,
{
// 实现 Display trait,用于格式化输出节点
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.next {
Some(node) => write!(f, "{}, {}", self.val, unsafe { node.as_ref() }),
None => write!(f, "{}", self.val),
Some(node) => write!(f, "{}, {}", self.val, unsafe { node.as_ref() }), // 输出当前节点值和下一个节点
None => write!(f, "{}", self.val), // 最后一个节点
}
}
}

#[cfg(test)]
mod tests {
use super::LinkedList;
Expand Down
32 changes: 30 additions & 2 deletions exercises/algorithm/algorithm10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
graph
This problem requires you to implement a basic graph functio
*/
// I AM NOT DONE


use std::collections::{HashMap, HashSet};
use std::fmt;
Expand All @@ -22,14 +22,42 @@ impl Graph for UndirectedGraph {
adjacency_table: HashMap::new(),
}
}

fn adjacency_table_mutable(&mut self) -> &mut HashMap<String, Vec<(String, i32)>> {
&mut self.adjacency_table
}

fn adjacency_table(&self) -> &HashMap<String, Vec<(String, i32)>> {
&self.adjacency_table
}

fn add_node(&mut self, node: &str) -> bool {
if !self.contains(node) {
self.adjacency_table_mutable().insert(node.to_string(), Vec::new());
true
} else {
false
}
}

fn add_edge(&mut self, edge: (&str, &str, i32)) {
//TODO
let (node_a, node_b, weight) = edge;

// Add nodes to the graph if they don't already exist
self.add_node(node_a);
self.add_node(node_b);

// Add edge from node_a to node_b
self.adjacency_table_mutable()
.get_mut(node_a)
.unwrap()
.push((node_b.to_string(), weight));

// Add edge from node_b to node_a (since it's an undirected graph)
self.adjacency_table_mutable()
.get_mut(node_b)
.unwrap()
.push((node_a.to_string(), weight));
}
}
pub trait Graph {
Expand Down
22 changes: 21 additions & 1 deletion exercises/algorithm/algorithm2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
double linked list reverse
This problem requires you to reverse a doubly linked list
*/
// I AM NOT DONE

use std::fmt::{self, Display, Formatter};
use std::ptr::NonNull;
Expand Down Expand Up @@ -74,6 +73,27 @@ impl<T> LinkedList<T> {
}
pub fn reverse(&mut self){
// TODO
let mut current = self.start;

// 遍历链表并交换每个节点的 `next` 和 `prev` 指针
while let Some(mut node_ptr) = current {
unsafe {
let node = node_ptr.as_mut(); // 获取当前节点的可变引用

// 交换 `next` 和 `prev` 指针
let temp = node.next; // 保存当前的 `next` 指针
node.next = node.prev; // 将 `prev` 赋给 `next`
node.prev = temp; // 将之前保存的 `next` 赋给 `prev`
}

// 移动到下一个节点
current = unsafe { (*current.unwrap().as_ptr()).prev };
}

// 反转链表后,更新 `start` 和 `end` 指针
std::mem::swap(&mut self.start, &mut self.end);


}
}

Expand Down
16 changes: 13 additions & 3 deletions exercises/algorithm/algorithm3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@
This problem requires you to implement a sorting algorithm
you can use bubble sorting, insertion sorting, heap sorting, etc.
*/
// I AM NOT DONE

fn sort<T>(array: &mut [T]){
//TODO

fn sort<T: Ord + Clone>(array: &mut [T]) {
let len = array.len();
for i in 1..len {
let key = array[i].clone(); // 克隆当前元素
let mut j = i; // 从当前元素的前一个开始比较
while j > 0 && array[j - 1] > key {
array[j] = array[j - 1].clone(); // 右移元素
j -= 1;
}
array[j] = key; // 插入当前元素
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading