summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2025-11-22 20:16:50 +0800
committer魏曹先生 <1992414357@qq.com>2025-11-22 20:16:50 +0800
commitfcff43f38ea3b83a554452ed8c11b0d295ad9dba (patch)
tree321ae228cdab97a5948b7c15c2c1f0471e08983f
parent97089d19a4b339a622d78e48a41f1d67273752fd (diff)
Move quick sort utility to data_struct module
-rw-r--r--src/bin/jv.rs2
-rw-r--r--src/utils.rs1
-rw-r--r--src/utils/sort.rs233
3 files changed, 1 insertions, 235 deletions
diff --git a/src/bin/jv.rs b/src/bin/jv.rs
index 4245e6a..06215f2 100644
--- a/src/bin/jv.rs
+++ b/src/bin/jv.rs
@@ -3,6 +3,7 @@ use just_enough_vcs::{
system::action_system::{action::ActionContext, action_pool::ActionPool},
utils::{
cfg_file::config::ConfigFile,
+ data_struct::dada_sort::quick_sort_with_cmp,
string_proc::{self, snake_case},
tcp_connection::instance::ConnectionInstance,
},
@@ -65,7 +66,6 @@ use just_enough_vcs_cli::{
fs::move_across_partitions,
input::{confirm_hint, confirm_hint_or, input_with_editor, show_in_pager},
socket_addr_helper,
- sort::quick_sort_with_cmp,
},
};
use rust_i18n::{set_locale, t};
diff --git a/src/utils.rs b/src/utils.rs
index ebcda2c..958c487 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -4,4 +4,3 @@ pub mod fs;
pub mod input;
pub mod logger;
pub mod socket_addr_helper;
-pub mod sort;
diff --git a/src/utils/sort.rs b/src/utils/sort.rs
deleted file mode 100644
index 26cbf57..0000000
--- a/src/utils/sort.rs
+++ /dev/null
@@ -1,233 +0,0 @@
-/// Quick sort a slice with a custom comparison function
-///
-/// # Arguments
-/// * `arr` - The mutable slice to be sorted
-/// * `inverse` - Sort direction: true for descending, false for ascending
-/// * `compare` - Comparison function that returns -1, 0, or 1 indicating the relative order of two elements
-pub fn quick_sort_with_cmp<T, F>(arr: &mut [T], inverse: bool, compare: F)
-where
- F: Fn(&T, &T) -> i32,
-{
- quick_sort_with_cmp_helper(arr, inverse, &compare);
-}
-
-/// Quick sort for types that implement the PartialOrd trait
-///
-/// # Arguments
-/// * `arr` - The mutable slice to be sorted
-/// * `inverse` - Sort direction: true for descending, false for ascending
-pub fn quick_sort<T: PartialOrd>(arr: &mut [T], inverse: bool) {
- quick_sort_with_cmp(arr, inverse, |a, b| {
- if a < b {
- -1
- } else if a > b {
- 1
- } else {
- 0
- }
- });
-}
-
-fn quick_sort_with_cmp_helper<T, F>(arr: &mut [T], inverse: bool, compare: &F)
-where
- F: Fn(&T, &T) -> i32,
-{
- if arr.len() <= 1 {
- return;
- }
-
- let pivot_index = partition_with_cmp(arr, inverse, compare);
- let (left, right) = arr.split_at_mut(pivot_index);
-
- quick_sort_with_cmp_helper(left, inverse, compare);
- quick_sort_with_cmp_helper(&mut right[1..], inverse, compare);
-}
-
-fn partition_with_cmp<T, F>(arr: &mut [T], inverse: bool, compare: &F) -> usize
-where
- F: Fn(&T, &T) -> i32,
-{
- let len = arr.len();
- let pivot_index = len / 2;
-
- arr.swap(pivot_index, len - 1);
-
- let mut i = 0;
- for j in 0..len - 1 {
- let cmp_result = compare(&arr[j], &arr[len - 1]);
- let should_swap = if inverse {
- cmp_result > 0
- } else {
- cmp_result < 0
- };
-
- if should_swap {
- arr.swap(i, j);
- i += 1;
- }
- }
-
- arr.swap(i, len - 1);
- i
-}
-
-#[cfg(test)]
-pub mod sort_test {
- use crate::utils::sort::quick_sort;
- use crate::utils::sort::quick_sort_with_cmp;
-
- #[test]
- fn test_quick_sort_ascending() {
- let mut arr = [3, 1, 4, 1, 5, 9, 2, 6];
- quick_sort(&mut arr, false);
- assert_eq!(arr, [1, 1, 2, 3, 4, 5, 6, 9]);
- }
-
- #[test]
- fn test_quick_sort_descending() {
- let mut arr = [3, 1, 4, 1, 5, 9, 2, 6];
- quick_sort(&mut arr, true);
- assert_eq!(arr, [9, 6, 5, 4, 3, 2, 1, 1]);
- }
-
- #[test]
- fn test_quick_sort_single() {
- let mut arr = [42];
- quick_sort(&mut arr, false);
- assert_eq!(arr, [42]);
- }
-
- #[test]
- fn test_quick_sort_already_sorted() {
- let mut arr = [1, 2, 3, 4, 5];
- quick_sort(&mut arr, false);
- assert_eq!(arr, [1, 2, 3, 4, 5]);
- }
-
- #[test]
- fn test_quick_sort_with_cmp_by_count() {
- #[derive(Debug, PartialEq)]
- struct WordCount {
- word: String,
- count: usize,
- }
-
- let mut words = vec![
- WordCount {
- word: "apple".to_string(),
- count: 3,
- },
- WordCount {
- word: "banana".to_string(),
- count: 1,
- },
- WordCount {
- word: "cherry".to_string(),
- count: 5,
- },
- WordCount {
- word: "date".to_string(),
- count: 2,
- },
- ];
-
- quick_sort_with_cmp(&mut words, false, |a, b| {
- if a.count < b.count {
- -1
- } else if a.count > b.count {
- 1
- } else {
- 0
- }
- });
-
- assert_eq!(
- words,
- vec![
- WordCount {
- word: "banana".to_string(),
- count: 1
- },
- WordCount {
- word: "date".to_string(),
- count: 2
- },
- WordCount {
- word: "apple".to_string(),
- count: 3
- },
- WordCount {
- word: "cherry".to_string(),
- count: 5
- },
- ]
- );
-
- quick_sort_with_cmp(&mut words, true, |a, b| {
- if a.count < b.count {
- -1
- } else if a.count > b.count {
- 1
- } else {
- 0
- }
- });
-
- assert_eq!(
- words,
- vec![
- WordCount {
- word: "cherry".to_string(),
- count: 5
- },
- WordCount {
- word: "apple".to_string(),
- count: 3
- },
- WordCount {
- word: "date".to_string(),
- count: 2
- },
- WordCount {
- word: "banana".to_string(),
- count: 1
- },
- ]
- );
- }
-
- #[test]
- fn test_quick_sort_with_cmp_by_first_letter() {
- let mut words = vec!["zebra", "apple", "banana", "cherry", "date"];
-
- quick_sort_with_cmp(&mut words, false, |a, b| {
- let a_first = a.chars().next().unwrap();
- let b_first = b.chars().next().unwrap();
-
- if a_first < b_first {
- -1
- } else if a_first > b_first {
- 1
- } else {
- 0
- }
- });
-
- assert_eq!(words, vec!["apple", "banana", "cherry", "date", "zebra"]);
-
- quick_sort_with_cmp(&mut words, true, |a, b| {
- let a_first = a.chars().next().unwrap();
- let b_first = b.chars().next().unwrap();
-
- if a_first < b_first {
- -1
- } else if a_first > b_first {
- 1
- } else {
- 0
- }
- });
-
- assert_eq!(words, vec!["zebra", "date", "cherry", "banana", "apple"]);
- }
-}