├── .gitignore ├── .travis.yml ├── Cargo.toml ├── README.md └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: rust 3 | rust: 4 | - nightly 5 | - beta 6 | - stable 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "quicksort" 3 | version = "1.1.0" 4 | authors = ["Simon Sapin "] 5 | license = "MPL-2.0" 6 | description = "A quicksort implementation for in-place sorting." 7 | repository = "https://github.com/servo/rust-quicksort" 8 | documentation = "http://doc.servo.org/quicksort/" 9 | 10 | [lib] 11 | name = "quicksort" 12 | path = "lib.rs" 13 | doctest = false 14 | 15 | [dev-dependencies] 16 | rand = "0.3" 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **This library is deprecated**. If you want a performant in-place sorting algorithm, you should probably use [`sort_unstable`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.sort_unstable) from the standard library, instead. 2 | 3 | # rust-quicksort 4 | 5 | [Documentation](http://doc.servo.org/quicksort/) 6 | -------------------------------------------------------------------------------- /lib.rs: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | //! In-place sorting. 6 | #![cfg_attr(not(test), no_std)] 7 | #[cfg(test)] 8 | extern crate std as core; 9 | 10 | use core::cmp::Ordering; 11 | 12 | fn quicksort_helper(arr: &mut [T], left: isize, right: isize, compare: &F) 13 | where F: Fn(&T, &T) -> Ordering { 14 | if right <= left { 15 | return 16 | } 17 | 18 | let mut i: isize = left - 1; 19 | let mut j: isize = right; 20 | let mut p: isize = i; 21 | let mut q: isize = j; 22 | unsafe { 23 | let v: *mut T = &mut arr[right as usize]; 24 | loop { 25 | i += 1; 26 | while compare(&arr[i as usize], &*v) == Ordering::Less { 27 | i += 1 28 | } 29 | j -= 1; 30 | while compare(&*v, &arr[j as usize]) == Ordering::Less { 31 | if j == left { 32 | break 33 | } 34 | j -= 1; 35 | } 36 | if i >= j { 37 | break 38 | } 39 | arr.swap(i as usize, j as usize); 40 | if compare(&arr[i as usize], &*v) == Ordering::Equal { 41 | p += 1; 42 | arr.swap(p as usize, i as usize) 43 | } 44 | if compare(&*v, &arr[j as usize]) == Ordering::Equal { 45 | q -= 1; 46 | arr.swap(j as usize, q as usize) 47 | } 48 | } 49 | } 50 | 51 | arr.swap(i as usize, right as usize); 52 | j = i - 1; 53 | i += 1; 54 | let mut k: isize = left; 55 | while k < p { 56 | arr.swap(k as usize, j as usize); 57 | k += 1; 58 | j -= 1; 59 | assert!(k < arr.len() as isize); 60 | } 61 | k = right - 1; 62 | while k > q { 63 | arr.swap(i as usize, k as usize); 64 | k -= 1; 65 | i += 1; 66 | assert!(k != 0); 67 | } 68 | 69 | quicksort_helper(arr, left, j, compare); 70 | quicksort_helper(arr, i, right, compare); 71 | } 72 | 73 | 74 | /// An in-place quicksort. 75 | /// 76 | /// The algorithm is from Sedgewick and Bentley, "Quicksort is Optimal": 77 | /// http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf 78 | pub fn quicksort_by(arr: &mut [T], compare: F) where F: Fn(&T, &T) -> Ordering { 79 | if arr.len() <= 1 { 80 | return 81 | } 82 | 83 | let len = arr.len(); 84 | quicksort_helper(arr, 0, (len - 1) as isize, &compare); 85 | } 86 | 87 | 88 | /// An in-place quicksort for ordered items. 89 | #[inline] 90 | pub fn quicksort(arr: &mut [T]) where T: Ord { 91 | quicksort_by(arr, |a, b| a.cmp(b)) 92 | } 93 | 94 | 95 | #[cfg(test)] 96 | extern crate rand; 97 | 98 | #[cfg(test)] 99 | pub mod test { 100 | use rand::{self, Rng}; 101 | 102 | use super::quicksort; 103 | 104 | #[test] 105 | pub fn random() { 106 | let mut rng = rand::thread_rng(); 107 | for _ in 0u32 .. 50000u32 { 108 | let len: usize = rng.gen(); 109 | let mut v: Vec = rng.gen_iter::().take((len % 32) + 1).collect(); 110 | quicksort(&mut v); 111 | for i in 0 .. v.len() - 1 { 112 | assert!(v[i] <= v[i + 1]) 113 | } 114 | } 115 | } 116 | } 117 | --------------------------------------------------------------------------------