Skip to content

Commit df7da31

Browse files
committed
update
1 parent 1f80725 commit df7da31

File tree

17 files changed

+302
-44
lines changed

17 files changed

+302
-44
lines changed

exercises/algorithm/algorithm1.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
single linked list merge
33
This problem requires you to merge two ordered singly linked lists into one ordered singly linked list
44
*/
5-
// I AM NOT DONE
65

76
use std::fmt::{self, Display, Formatter};
87
use std::ptr::NonNull;
@@ -70,14 +69,42 @@ impl<T> LinkedList<T> {
7069
}
7170
}
7271
pub fn merge(list_a:LinkedList<T>,list_b:LinkedList<T>) -> Self
73-
{
74-
//TODO
75-
Self {
76-
length: 0,
77-
start: None,
78-
end: None,
72+
where
73+
T: Ord + Copy,
74+
{
75+
let mut res = LinkedList::new();
76+
let mut a = list_a.start;
77+
let mut b = list_b.start;
78+
79+
// 比较两个链表当前节点的值,较小的值追加到结果链表并推进对应指针
80+
while a.is_some() && b.is_some() {
81+
let a_ptr = a.unwrap();
82+
let b_ptr = b.unwrap();
83+
let a_val = unsafe { (*a_ptr.as_ptr()).val };
84+
let b_val = unsafe { (*b_ptr.as_ptr()).val };
85+
if a_val <= b_val {
86+
res.add(a_val);
87+
a = unsafe { (*a_ptr.as_ptr()).next };
88+
} else {
89+
res.add(b_val);
90+
b = unsafe { (*b_ptr.as_ptr()).next };
91+
}
7992
}
80-
}
93+
94+
// 追加剩余部分
95+
while let Some(a_ptr) = a {
96+
let a_val = unsafe { (*a_ptr.as_ptr()).val };
97+
res.add(a_val);
98+
a = unsafe { (*a_ptr.as_ptr()).next };
99+
}
100+
while let Some(b_ptr) = b {
101+
let b_val = unsafe { (*b_ptr.as_ptr()).val };
102+
res.add(b_val);
103+
b = unsafe { (*b_ptr.as_ptr()).next };
104+
}
105+
106+
res
107+
}
81108
}
82109

83110
impl<T> Display for LinkedList<T>

exercises/algorithm/algorithm10.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
graph
33
This problem requires you to implement a basic graph functio
44
*/
5-
// I AM NOT DONE
65

76
use std::collections::{HashMap, HashSet};
87
use std::fmt;
@@ -30,6 +29,21 @@ impl Graph for UndirectedGraph {
3029
}
3130
fn add_edge(&mut self, edge: (&str, &str, i32)) {
3231
//TODO
32+
let (from, to, weight) = edge;
33+
// add nodes if missing
34+
self.adjacency_table
35+
.entry(from.to_string())
36+
.or_insert_with(Vec::new);
37+
self.adjacency_table
38+
.entry(to.to_string())
39+
.or_insert_with(Vec::new);
40+
// push both directions (undirected)
41+
if let Some(neighs) = self.adjacency_table.get_mut(from) {
42+
neighs.push((to.to_string(), weight));
43+
}
44+
if let Some(neighs) = self.adjacency_table.get_mut(to) {
45+
neighs.push((from.to_string(), weight));
46+
}
3347
}
3448
}
3549
pub trait Graph {
@@ -38,10 +52,17 @@ pub trait Graph {
3852
fn adjacency_table(&self) -> &HashMap<String, Vec<(String, i32)>>;
3953
fn add_node(&mut self, node: &str) -> bool {
4054
//TODO
41-
true
55+
if self.adjacency_table().get(node).is_some() {
56+
false
57+
} else {
58+
self.adjacency_table_mutable()
59+
.insert(node.to_string(), Vec::new());
60+
true
61+
}
4262
}
4363
fn add_edge(&mut self, edge: (&str, &str, i32)) {
4464
//TODO
65+
let _ = edge;
4566
}
4667
fn contains(&self, node: &str) -> bool {
4768
self.adjacency_table().get(node).is_some()

exercises/algorithm/algorithm2.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
double linked list reverse
33
This problem requires you to reverse a doubly linked list
44
*/
5-
// I AM NOT DONE
65

76
use std::fmt::{self, Display, Formatter};
87
use std::ptr::NonNull;
@@ -73,7 +72,19 @@ impl<T> LinkedList<T> {
7372
}
7473
}
7574
pub fn reverse(&mut self){
76-
// TODO
75+
let mut current = self.start;
76+
let mut prev = None;
77+
self.end = self.start;
78+
while let Some(node_ptr) = current {
79+
let next = unsafe { (*node_ptr.as_ptr()).next };
80+
unsafe {
81+
(*node_ptr.as_ptr()).next = prev;
82+
(*node_ptr.as_ptr()).prev = next;
83+
}
84+
prev = current;
85+
current = next;
86+
}
87+
self.start = prev;
7788
}
7889
}
7990

exercises/algorithm/algorithm3.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,21 @@
33
This problem requires you to implement a sorting algorithm
44
you can use bubble sorting, insertion sorting, heap sorting, etc.
55
*/
6-
// I AM NOT DONE
76

8-
fn sort<T>(array: &mut [T]){
9-
//TODO
10-
}
7+
fn sort<T>(array: &mut [T])
8+
where
9+
T: Ord + Copy,
10+
{
11+
let len = array.len();
12+
for i in 0..len {
13+
for j in 0..len -i - 1{
14+
if array[j] > array[j+1]{
15+
array.swap(j,j+1);
16+
}
17+
}
18+
}
19+
}
20+
1121
#[cfg(test)]
1222
mod tests {
1323
use super::*;

exercises/algorithm/algorithm4.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
This problem requires you to implement a basic interface for a binary tree
44
*/
55

6-
//I AM NOT DONE
76
use std::cmp::Ordering;
87
use std::fmt::Debug;
98

@@ -51,12 +50,28 @@ where
5150
// Insert a value into the BST
5251
fn insert(&mut self, value: T) {
5352
//TODO
53+
match self.root {
54+
None => {
55+
self.root = Some(Box::new(TreeNode::new(value)));
56+
}
57+
Some(ref mut node) => {
58+
node.insert(value);
59+
}
60+
}
5461
}
5562

5663
// Search for a value in the BST
5764
fn search(&self, value: T) -> bool {
5865
//TODO
59-
true
66+
let mut cur = &self.root;
67+
while let Some(ref node) = cur {
68+
match value.cmp(&node.value) {
69+
Ordering::Equal => return true,
70+
Ordering::Less => cur = &node.left,
71+
Ordering::Greater => cur = &node.right,
72+
}
73+
}
74+
false
6075
}
6176
}
6277

@@ -67,6 +82,24 @@ where
6782
// Insert a node into the tree
6883
fn insert(&mut self, value: T) {
6984
//TODO
85+
match value.cmp(&self.value) {
86+
Ordering::Less => {
87+
if let Some(ref mut left) = self.left {
88+
left.insert(value);
89+
} else {
90+
self.left = Some(Box::new(TreeNode::new(value)));
91+
}
92+
}
93+
Ordering::Greater => {
94+
if let Some(ref mut right) = self.right {
95+
right.insert(value);
96+
} else {
97+
self.right = Some(Box::new(TreeNode::new(value)));
98+
}
99+
}
100+
Ordering::Equal => {
101+
}
102+
}
70103
}
71104
}
72105

exercises/algorithm/algorithm5.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
This problem requires you to implement a basic BFS algorithm
44
*/
55

6-
//I AM NOT DONE
76
use std::collections::VecDeque;
87

98
// Define a graph
@@ -29,8 +28,28 @@ impl Graph {
2928
fn bfs_with_return(&self, start: usize) -> Vec<usize> {
3029

3130
//TODO
31+
let n = self.adj.len();
32+
let mut visit_order = Vec::new();
33+
if start >= n {
34+
return visit_order;
35+
}
36+
37+
let mut visited = vec![false; n];
38+
let mut queue: VecDeque<usize> = VecDeque::new();
39+
40+
visited[start] = true;
41+
queue.push_back(start);
42+
43+
while let Some(u) = queue.pop_front() {
44+
visit_order.push(u);
45+
for &v in &self.adj[u] {
46+
if v < n && !visited[v] {
47+
visited[v] = true; // 标记已访问以避免重复入队
48+
queue.push_back(v);
49+
}
50+
}
51+
}
3252

33-
let mut visit_order = vec![];
3453
visit_order
3554
}
3655
}

exercises/algorithm/algorithm6.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
This problem requires you to implement a basic DFS traversal
44
*/
55

6-
// I AM NOT DONE
76
use std::collections::HashSet;
87

98
struct Graph {
@@ -24,6 +23,16 @@ impl Graph {
2423

2524
fn dfs_util(&self, v: usize, visited: &mut HashSet<usize>, visit_order: &mut Vec<usize>) {
2625
//TODO
26+
if !visited.insert(v) {
27+
return;
28+
}
29+
visit_order.push(v);
30+
31+
for &nei in &self.adj[v] {
32+
if !visited.contains(&nei) {
33+
self.dfs_util(nei, visited, visit_order);
34+
}
35+
}
2736
}
2837

2938
// Perform a depth-first search on the graph, return the order of visited nodes

exercises/algorithm/algorithm7.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
This question requires you to use a stack to achieve a bracket match
44
*/
55

6-
// I AM NOT DONE
76
#[derive(Debug)]
87
struct Stack<T> {
98
size: usize,
@@ -32,7 +31,12 @@ impl<T> Stack<T> {
3231
}
3332
fn pop(&mut self) -> Option<T> {
3433
// TODO
35-
None
34+
if self.size == 0 {
35+
None
36+
} else {
37+
self.size -= 1;
38+
self.data.pop()
39+
}
3640
}
3741
fn peek(&self) -> Option<&T> {
3842
if 0 == self.size {
@@ -102,7 +106,17 @@ impl<'a, T> Iterator for IterMut<'a, T> {
102106
fn bracket_match(bracket: &str) -> bool
103107
{
104108
//TODO
105-
true
109+
let mut st: Stack<char> = Stack::new();
110+
for ch in bracket.chars() {
111+
match ch {
112+
'(' | '[' | '{' => st.push(ch),
113+
')' => if st.pop() != Some('(') { return false },
114+
']' => if st.pop() != Some('[') { return false },
115+
'}' => if st.pop() != Some('{') { return false },
116+
_ => {}
117+
}
118+
}
119+
st.is_empty()
106120
}
107121

108122
#[cfg(test)]

exercises/algorithm/algorithm8.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
queue
33
This question requires you to use queues to implement the functionality of the stac
44
*/
5-
// I AM NOT DONE
65

76
#[derive(Debug)]
87
pub struct Queue<T> {
@@ -68,14 +67,20 @@ impl<T> myStack<T> {
6867
}
6968
pub fn push(&mut self, elem: T) {
7069
//TODO
70+
self.q2.enqueue(elem);
71+
while !self.q1.is_empty() {
72+
let v = self.q1.dequeue().unwrap();
73+
self.q2.enqueue(v);
74+
}
75+
std::mem::swap(&mut self.q1, &mut self.q2);
7176
}
7277
pub fn pop(&mut self) -> Result<T, &str> {
7378
//TODO
74-
Err("Stack is empty")
79+
self.q1.dequeue().map_err(|_| "Stack is empty")
7580
}
7681
pub fn is_empty(&self) -> bool {
7782
//TODO
78-
true
83+
self.q1.is_empty()
7984
}
8085
}
8186

0 commit comments

Comments
 (0)