Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bb69508

Browse files
添加 冒泡排序、选择排序、插入排序、归并排序、快速排序 的Rust实现
1 parent f56cfad commit bb69508

File tree

9 files changed

+623
-1
lines changed

9 files changed

+623
-1
lines changed

‎.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ _book
1919
*.iml
2020

2121
src/javaSortTest/target/
22+
23+
src/rust/target/

‎1.bubbleSort.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,23 @@ function bubbleSort($arr)
129129
return $arr;
130130
}
131131
```
132+
133+
## 10. Rust 代码实现
134+
135+
```rust
136+
fn bubble_sort<T: Ord>(slice: &mut [T]) {
137+
for i in 1..=slice.len() {
138+
for j in 0..(slice.len() - i) {
139+
match slice[j].cmp(&slice[j + 1]) {
140+
Ordering::Less | Ordering::Equal => {
141+
// Do nothing
142+
}
143+
Ordering::Greater => {
144+
slice.swap(j, j + 1);
145+
}
146+
}
147+
}
148+
}
149+
}
150+
```
151+

‎2.selectionSort.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,20 @@ function selectionSort($arr)
126126
return $arr;
127127
}
128128
```
129+
130+
## 8. Rust 代码实现
131+
132+
```rust
133+
fn selection_sort<T: Ord>(slice: &mut [T]) {
134+
for i in 0..slice.len() {
135+
let mut selected = i;
136+
for j in (i + 1)..slice.len() {
137+
if slice[j] < slice[selected] {
138+
selected = j;
139+
}
140+
}
141+
142+
slice.swap(i, selected);
143+
}
144+
}
145+
```

‎3.insertionSort.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,19 @@ function insertionSort($arr)
118118
return $arr;
119119
}
120120
```
121+
122+
## 8. Rust 代码实现
123+
124+
```rust
125+
fn insertion_sort<T: Ord>(slice: &mut [T]) {
126+
for i in 1..slice.len() {
127+
for j in (1..=i).rev() {
128+
if slice[j] < slice[j - 1] {
129+
slice.swap(j, j - 1);
130+
} else {
131+
break;
132+
}
133+
}
134+
}
135+
}
136+
```

‎5.mergeSort.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,144 @@ void mergeSort(vector<int>& arr, int l, int r) { // sort the range [l, r) in arr
260260
merge(arr, l, mid, r);
261261
}
262262
```
263+
264+
## 10. Rust 代码实现
265+
266+
```rust
267+
/// 实现 1:
268+
/// Safe Rust 实现,需要大量浅复制(move),但不需要深拷贝,对primitive type排序较慢,但对没有 Copy Trait 的类型较快
269+
fn merge_sort<T: Ord>(mut v: Vec<T>) -> Vec<T> {
270+
if v.len() < 2 {
271+
return v;
272+
}
273+
274+
// Split the right half and sort them first
275+
let mut right = merge_sort(v.split_off(v.len() / 2));
276+
let mut left = merge_sort(v);
277+
278+
let mut result = Vec::new();
279+
280+
// 反向merge,因为 `Vec::remove(0)` 的复杂度是 `O(n)` 而且需要大量复制
281+
while !left.is_empty() && !right.is_empty() {
282+
if left.last().unwrap() > right.last().unwrap() {
283+
result.push(left.pop().unwrap());
284+
} else {
285+
result.push(right.pop().unwrap());
286+
}
287+
}
288+
result.extend(left.into_iter().rev());
289+
result.extend(right.into_iter().rev());
290+
result.reverse();
291+
292+
result
293+
}
294+
295+
296+
/// 实现 2:
297+
/// Safe Rust 实现,使用相对更少的复制,但需要更多的深拷贝。Primitive type排序速度更快,需要深拷贝的类型速度更慢
298+
fn merge_sort2<T: Ord + Clone>(v: &mut [T]) {
299+
if v.len() < 2 {
300+
return;
301+
}
302+
303+
let mid_idx = v.len() / 2;
304+
305+
merge_sort2(&mut v[..mid_idx]);
306+
merge_sort2(&mut v[mid_idx..]);
307+
308+
let mut temporary = Vec::with_capacity(v.len());
309+
310+
let mut l = 0;
311+
let mut r = mid_idx;
312+
313+
while l < mid_idx && r < v.len() {
314+
if v[l] < v[r] {
315+
temporary.push(v[l].clone());
316+
l += 1;
317+
} else {
318+
temporary.push(v[r].clone());
319+
r += 1;
320+
}
321+
}
322+
temporary.extend(v[l..mid_idx].iter().cloned());
323+
temporary.extend(v[r..].iter().cloned());
324+
325+
for (item, dest) in temporary.into_iter().zip(v.iter_mut()) {
326+
*dest = item;
327+
}
328+
}
329+
330+
331+
/// 实现 3:
332+
/// Unsafe Rust 实现,类似实现2,但使用 unsafe 避免了深拷贝,性能优于实现1与实现2
333+
fn merge_sort3<T: Ord>(v: &mut [T]) {
334+
if v.len() < 2 {
335+
return;
336+
}
337+
338+
// 可以在遇到较短的数组时使用插入排序,性能较佳。但即使不使用插入排序,此实现性能依然优于实现1与实现2
339+
if v.len() < 32 {
340+
insertion_sort(v);
341+
return;
342+
}
343+
344+
let mid_idx = v.len() / 2;
345+
346+
merge_sort3(&mut v[..mid_idx]);
347+
merge_sort3(&mut v[mid_idx..]);
348+
349+
let alloc_array = |size: usize| -> *mut T {
350+
// 等同于C中: `(T*)malloc(sizeof(T) * size)`
351+
unsafe {
352+
std::alloc::alloc(
353+
std::alloc::Layout::array::<T>(size).unwrap_unchecked(),
354+
) as *mut T
355+
}
356+
};
357+
let dealloc_array = |ptr: *mut T, size: usize| unsafe {
358+
// 等同于C中: `free(ptr)`
359+
std::alloc::dealloc(
360+
ptr as *mut u8,
361+
std::alloc::Layout::array::<T>(size).unwrap_unchecked(),
362+
)
363+
};
364+
365+
let temporary = alloc_array(v.len());
366+
let mut used_len = 0;
367+
368+
let mut l = 0;
369+
let mut r = mid_idx;
370+
371+
unsafe {
372+
while l < mid_idx && r < v.len() {
373+
if v[l] < v[r] {
374+
temporary
375+
.add(used_len)
376+
.copy_from_nonoverlapping(v.as_ptr().add(l), 1);
377+
l += 1;
378+
} else {
379+
temporary
380+
.add(used_len)
381+
.copy_from_nonoverlapping(v.as_ptr().add(r), 1);
382+
r += 1;
383+
}
384+
used_len += 1;
385+
}
386+
387+
let left_remain = mid_idx - l;
388+
temporary
389+
.add(used_len)
390+
.copy_from_nonoverlapping(v.as_ptr().add(l), left_remain);
391+
used_len += left_remain;
392+
393+
let right_remain = v.len() - r;
394+
temporary
395+
.add(used_len)
396+
.copy_from_nonoverlapping(v.as_ptr().add(r), right_remain);
397+
398+
v.as_mut_ptr().copy_from_nonoverlapping(temporary, v.len());
399+
}
400+
401+
dealloc_array(temporary, v.len());
402+
}
403+
```

‎6.quickSort.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ func swap(arr []int, i, j int) {
156156
## 6. C++版
157157

158158

159-
```C++
159+
```cpp
160160
//严蔚敏《数据结构》标准分割函数
161161
Paritition1(int A[], int low, int high) {
162162
int pivot = A[low];
@@ -253,3 +253,33 @@ function quickSort($arr)
253253
return array_merge($leftArray, $rightArray);
254254
}
255255
```
256+
257+
## 9. Rust 代码实现
258+
259+
```rust
260+
fn quick_sort<T: Ord>(slice: &mut [T]) {
261+
const PIVOT: usize = 0;
262+
263+
match slice.len().cmp(&2) {
264+
Ordering::Less => {}
265+
Ordering::Equal => {
266+
if slice[0] > slice[1] {
267+
slice.swap(0, 1);
268+
}
269+
}
270+
Ordering::Greater => {
271+
let mut swap_point = 0;
272+
for i in 1..slice.len() {
273+
if slice[i] < slice[PIVOT] {
274+
swap_point += 1;
275+
slice.swap(swap_point, i);
276+
}
277+
}
278+
slice.swap(PIVOT, swap_point);
279+
280+
quick_sort(&mut slice[..swap_point]);
281+
quick_sort(&mut slice[(swap_point + 1)..]);
282+
}
283+
}
284+
}
285+
```

‎src/rust/Cargo.lock

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

‎src/rust/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "rust"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
10+
rand = "0.8"

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /