Skip to content

Commit 20e4236

Browse files
yllmisyllmis
authored andcommitted
update
1 parent ca6dc3f commit 20e4236

File tree

10 files changed

+203
-117
lines changed

10 files changed

+203
-117
lines changed

exercises/algorithm/algorithm1.rs

Lines changed: 120 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/*
2-
single linked list merge
3-
This problem requires you to merge two ordered singly linked lists into one ordered singly linked list
2+
single linked list merge
3+
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;
@@ -16,10 +15,7 @@ struct Node<T> {
1615

1716
impl<T> Node<T> {
1817
fn new(t: T) -> Node<T> {
19-
Node {
20-
val: t,
21-
next: None,
22-
}
18+
Node { val: t, next: None }
2319
}
2420
}
2521
#[derive(Debug)]
@@ -69,15 +65,83 @@ impl<T> LinkedList<T> {
6965
},
7066
}
7167
}
72-
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,
68+
pub fn merge(mut list_a: LinkedList<T>, mut list_b: LinkedList<T>) -> Self
69+
//TODO
70+
where
71+
T: Ord,
72+
{
73+
let mut head: Option<NonNull<Node<T>>> = None;
74+
let mut tail: Option<NonNull<Node<T>>> = None;
75+
76+
let mut pa = list_a.start;
77+
let mut pb = list_b.start;
78+
79+
// 交替选择较小节点接到结果链表末尾
80+
while pa.is_some() && pb.is_some() {
81+
let pick;
82+
unsafe {
83+
let ra = pa.unwrap();
84+
let rb = pb.unwrap();
85+
if (*ra.as_ptr()).val <= (*rb.as_ptr()).val {
86+
pick = pa;
87+
pa = (*ra.as_ptr()).next;
88+
} else {
89+
pick = pb;
90+
pb = (*rb.as_ptr()).next;
91+
}
92+
}
93+
if head.is_none() {
94+
head = pick;
95+
tail = pick;
96+
} else {
97+
unsafe {
98+
(*tail.unwrap().as_ptr()).next = pick;
99+
}
100+
tail = pick;
101+
}
79102
}
80-
}
103+
104+
// 剩余部分直接接上
105+
let remainder = if pa.is_some() { pa } else { pb };
106+
if head.is_none() {
107+
// 两个链表都为空或一个为空,结果就是 remainder
108+
head = remainder;
109+
// 找到尾节点
110+
if let Some(mut cur) = head {
111+
loop {
112+
let next = unsafe { (*cur.as_ptr()).next };
113+
if let Some(n) = next {
114+
cur = n;
115+
} else {
116+
break;
117+
}
118+
}
119+
tail = Some(cur);
120+
}
121+
} else if remainder.is_some() {
122+
unsafe {
123+
(*tail.unwrap().as_ptr()).next = remainder;
124+
}
125+
// 更新 tail 到 remainder 的末尾
126+
let mut cur = remainder.unwrap();
127+
loop {
128+
let next = unsafe { (*cur.as_ptr()).next };
129+
if let Some(n) = next {
130+
cur = n;
131+
} else {
132+
break;
133+
}
134+
}
135+
tail = Some(cur);
136+
}
137+
138+
let length = list_a.length + list_b.length;
139+
Self {
140+
length,
141+
start: head,
142+
end: tail,
143+
}
144+
}
81145
}
82146

83147
impl<T> Display for LinkedList<T>
@@ -130,44 +194,44 @@ mod tests {
130194

131195
#[test]
132196
fn test_merge_linked_list_1() {
133-
let mut list_a = LinkedList::<i32>::new();
134-
let mut list_b = LinkedList::<i32>::new();
135-
let vec_a = vec![1,3,5,7];
136-
let vec_b = vec![2,4,6,8];
137-
let target_vec = vec![1,2,3,4,5,6,7,8];
138-
139-
for i in 0..vec_a.len(){
140-
list_a.add(vec_a[i]);
141-
}
142-
for i in 0..vec_b.len(){
143-
list_b.add(vec_b[i]);
144-
}
145-
println!("list a {} list b {}", list_a,list_b);
146-
let mut list_c = LinkedList::<i32>::merge(list_a,list_b);
147-
println!("merged List is {}", list_c);
148-
for i in 0..target_vec.len(){
149-
assert_eq!(target_vec[i],*list_c.get(i as i32).unwrap());
150-
}
151-
}
152-
#[test]
153-
fn test_merge_linked_list_2() {
154-
let mut list_a = LinkedList::<i32>::new();
155-
let mut list_b = LinkedList::<i32>::new();
156-
let vec_a = vec![11,33,44,88,89,90,100];
157-
let vec_b = vec![1,22,30,45];
158-
let target_vec = vec![1,11,22,30,33,44,45,88,89,90,100];
159-
160-
for i in 0..vec_a.len(){
161-
list_a.add(vec_a[i]);
162-
}
163-
for i in 0..vec_b.len(){
164-
list_b.add(vec_b[i]);
165-
}
166-
println!("list a {} list b {}", list_a,list_b);
167-
let mut list_c = LinkedList::<i32>::merge(list_a,list_b);
168-
println!("merged List is {}", list_c);
169-
for i in 0..target_vec.len(){
170-
assert_eq!(target_vec[i],*list_c.get(i as i32).unwrap());
171-
}
172-
}
173-
}
197+
let mut list_a = LinkedList::<i32>::new();
198+
let mut list_b = LinkedList::<i32>::new();
199+
let vec_a = vec![1, 3, 5, 7];
200+
let vec_b = vec![2, 4, 6, 8];
201+
let target_vec = vec![1, 2, 3, 4, 5, 6, 7, 8];
202+
203+
for i in 0..vec_a.len() {
204+
list_a.add(vec_a[i]);
205+
}
206+
for i in 0..vec_b.len() {
207+
list_b.add(vec_b[i]);
208+
}
209+
println!("list a {} list b {}", list_a, list_b);
210+
let mut list_c = LinkedList::<i32>::merge(list_a, list_b);
211+
println!("merged List is {}", list_c);
212+
for i in 0..target_vec.len() {
213+
assert_eq!(target_vec[i], *list_c.get(i as i32).unwrap());
214+
}
215+
}
216+
#[test]
217+
fn test_merge_linked_list_2() {
218+
let mut list_a = LinkedList::<i32>::new();
219+
let mut list_b = LinkedList::<i32>::new();
220+
let vec_a = vec![11, 33, 44, 88, 89, 90, 100];
221+
let vec_b = vec![1, 22, 30, 45];
222+
let target_vec = vec![1, 11, 22, 30, 33, 44, 45, 88, 89, 90, 100];
223+
224+
for i in 0..vec_a.len() {
225+
list_a.add(vec_a[i]);
226+
}
227+
for i in 0..vec_b.len() {
228+
list_b.add(vec_b[i]);
229+
}
230+
println!("list a {} list b {}", list_a, list_b);
231+
let mut list_c = LinkedList::<i32>::merge(list_a, list_b);
232+
println!("merged List is {}", list_c);
233+
for i in 0..target_vec.len() {
234+
assert_eq!(target_vec[i], *list_c.get(i as i32).unwrap());
235+
}
236+
}
237+
}

exercises/algorithm/algorithm2.rs

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/*
2-
double linked list reverse
3-
This problem requires you to reverse a doubly linked list
2+
double linked list reverse
3+
This problem requires you to reverse a doubly linked list
44
*/
5-
// I AM NOT DONE
65

76
use std::fmt::{self, Display, Formatter};
7+
use std::mem::swap;
88
use std::ptr::NonNull;
99
use std::vec::*;
1010

@@ -72,9 +72,18 @@ impl<T> LinkedList<T> {
7272
},
7373
}
7474
}
75-
pub fn reverse(&mut self){
76-
// TODO
77-
}
75+
pub fn reverse(&mut self) {
76+
// TODO
77+
let mut current = self.start;
78+
while let Some(node_ptr) = current {
79+
unsafe {
80+
let node = node_ptr.as_ptr();
81+
swap(&mut (*node).next, &mut (*node).prev);
82+
current = (*node).prev;
83+
}
84+
}
85+
swap(&mut self.start, &mut self.end);
86+
}
7887
}
7988

8089
impl<T> Display for LinkedList<T>
@@ -127,33 +136,33 @@ mod tests {
127136

128137
#[test]
129138
fn test_reverse_linked_list_1() {
130-
let mut list = LinkedList::<i32>::new();
131-
let original_vec = vec![2,3,5,11,9,7];
132-
let reverse_vec = vec![7,9,11,5,3,2];
133-
for i in 0..original_vec.len(){
134-
list.add(original_vec[i]);
135-
}
136-
println!("Linked List is {}", list);
137-
list.reverse();
138-
println!("Reversed Linked List is {}", list);
139-
for i in 0..original_vec.len(){
140-
assert_eq!(reverse_vec[i],*list.get(i as i32).unwrap());
141-
}
142-
}
139+
let mut list = LinkedList::<i32>::new();
140+
let original_vec = vec![2, 3, 5, 11, 9, 7];
141+
let reverse_vec = vec![7, 9, 11, 5, 3, 2];
142+
for i in 0..original_vec.len() {
143+
list.add(original_vec[i]);
144+
}
145+
println!("Linked List is {}", list);
146+
list.reverse();
147+
println!("Reversed Linked List is {}", list);
148+
for i in 0..original_vec.len() {
149+
assert_eq!(reverse_vec[i], *list.get(i as i32).unwrap());
150+
}
151+
}
143152

144-
#[test]
145-
fn test_reverse_linked_list_2() {
146-
let mut list = LinkedList::<i32>::new();
147-
let original_vec = vec![34,56,78,25,90,10,19,34,21,45];
148-
let reverse_vec = vec![45,21,34,19,10,90,25,78,56,34];
149-
for i in 0..original_vec.len(){
150-
list.add(original_vec[i]);
151-
}
152-
println!("Linked List is {}", list);
153-
list.reverse();
154-
println!("Reversed Linked List is {}", list);
155-
for i in 0..original_vec.len(){
156-
assert_eq!(reverse_vec[i],*list.get(i as i32).unwrap());
157-
}
158-
}
159-
}
153+
#[test]
154+
fn test_reverse_linked_list_2() {
155+
let mut list = LinkedList::<i32>::new();
156+
let original_vec = vec![34, 56, 78, 25, 90, 10, 19, 34, 21, 45];
157+
let reverse_vec = vec![45, 21, 34, 19, 10, 90, 25, 78, 56, 34];
158+
for i in 0..original_vec.len() {
159+
list.add(original_vec[i]);
160+
}
161+
println!("Linked List is {}", list);
162+
list.reverse();
163+
println!("Reversed Linked List is {}", list);
164+
for i in 0..original_vec.len() {
165+
assert_eq!(reverse_vec[i], *list.get(i as i32).unwrap());
166+
}
167+
}
168+
}

exercises/algorithm/algorithm3.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
/*
2-
sort
3-
This problem requires you to implement a sorting algorithm
4-
you can use bubble sorting, insertion sorting, heap sorting, etc.
2+
sort
3+
This problem requires you to implement a sorting algorithm
4+
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
7+
fn sort<T: Ord>(array: &mut [T]) {
8+
//TODO
9+
let n = array.len();
10+
for i in 0..n {
11+
let mut j = i;
12+
while j > 0 && array[j] < array[j - 1] {
13+
array.swap(j, j - 1);
14+
j -= 1;
15+
}
16+
}
1017
}
1118
#[cfg(test)]
1219
mod tests {
@@ -18,16 +25,16 @@ mod tests {
1825
sort(&mut vec);
1926
assert_eq!(vec, vec![19, 37, 46, 57, 64, 73, 75, 91]);
2027
}
21-
#[test]
28+
#[test]
2229
fn test_sort_2() {
2330
let mut vec = vec![1];
2431
sort(&mut vec);
2532
assert_eq!(vec, vec![1]);
2633
}
27-
#[test]
34+
#[test]
2835
fn test_sort_3() {
2936
let mut vec = vec![99, 88, 77, 66, 55, 44, 33, 22, 11];
3037
sort(&mut vec);
3138
assert_eq!(vec, vec![11, 22, 33, 44, 55, 66, 77, 88, 99]);
3239
}
33-
}
40+
}

exercises/tests/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

exercises/tests/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "tests8"
3+
version = "0.0.1"
4+
edition = "2021"
5+
[[bin]]
6+
name = "tests8"
7+
path = "tests8.rs"

exercises/tests/build.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@ fn main() {
1010
.duration_since(std::time::UNIX_EPOCH)
1111
.unwrap()
1212
.as_secs(); // What's the use of this timestamp here?
13-
let your_command = format!(
14-
"Your command here with {}, please checkout exercises/tests/build.rs",
15-
timestamp
16-
);
17-
println!("cargo:{}", your_command);
13+
14+
println!("cargo:rustc-env=TEST_FOO={}", timestamp);
1815

1916
// In tests8, we should enable "pass" feature to make the
2017
// testcase return early. Fill in the command to tell
2118
// Cargo about that.
22-
let your_command = "Your command here, please checkout exercises/tests/build.rs";
23-
println!("cargo:{}", your_command);
19+
20+
println!("cargo:rustc-cfg=feature=\"pass\"");
2421
}

0 commit comments

Comments
 (0)