1use std::cmp::Ordering;
4
5pub fn test<T: Ord>(slice: &[T]) -> bool {
7 if slice.len() < 2 {
8 return true;
9 }
10
11 let mut iter = slice.iter();
12 let mut prev = iter.next().unwrap();
13 let mut curr = iter.next();
14
15 while curr != None {
16 let value = curr.unwrap();
17 if prev > value {
18 return false;
19 }
20
21 prev = value;
22 curr = iter.next();
23 }
24
25 true
26}
27
28pub fn is_sorted<T: Ord>(slice: &[T]) -> bool {
30 test(slice)
31}
32
33pub fn bubble<T: Ord>(slice: &mut [T]) {
47 if test(slice) {
48 return;
49 }
50
51 let mut n = slice.len();
52 while n > 1 {
53 let mut newn = 0;
54
55 for i in 1..n {
56 if slice[i - 1] > slice[i] {
57 slice.swap(i - 1, i);
58 newn = i;
59 }
60 }
61
62 n = newn;
63 }
64}
65
66pub fn quick_partition<T: Ord>(slice: &mut [T]) -> usize {
73 let n = slice.len();
76 let mut lo = 0;
77 let mut hi = n - 1;
78 let mut pivot = n - 1;
79
80 let mut equal = false;
81 loop {
82 if equal {
84 lo += 1;
85 equal = false;
86 }
87
88 while slice[lo] < slice[pivot] {
90 lo += 1;
91 }
92
93 while hi > 0 && slice[hi] > slice[pivot] {
95 hi -= 1;
96 }
97
98 if lo >= hi {
99 break;
101 } else if slice[lo] == slice[hi] {
102 equal = true;
103 } else {
104 if lo == pivot {
105 pivot = hi;
106 } else if hi == pivot {
107 pivot = lo;
108 }
109
110 slice.swap(lo, hi);
111 }
112 }
113
114 slice.swap(lo, pivot);
115 lo
116}
117
118pub fn quick<T: Ord>(slice: &mut [T]) {
132 if test(slice) {
133 return;
134 }
135 let partition = quick_partition(slice);
136 quick(&mut slice[..partition]);
137 quick(&mut slice[(partition + 1)..]);
138}
139
140pub fn merge<T: Ord + Clone>(slice: &mut [T]) {
155 if test(slice) {
156 return;
157 }
158
159 let mid = slice.len() / 2;
160
161 let mut left = Vec::new();
163 left.extend_from_slice(&slice[..mid]);
164 let mut left = &mut left[..];
165
166 merge(&mut left);
167 merge(&mut slice[mid..]);
168
169 let mut i = 0;
171 let mut j = 0;
172 loop {
173 let midj = mid + j;
174
175 if i == mid {
176 break;
178 } else if midj == slice.len() {
179 slice[(mid + i)..].clone_from_slice(&left[i..]);
182 break;
183 }
184
185 let ij = i + j;
186
187 match left[i].cmp(&slice[midj]) {
188 Ordering::Less => {
189 slice[ij] = left[i].clone();
190 i += 1;
191 }
192 Ordering::Equal => {
193 let e = left[i].clone();
196
197 slice[ij] = e.clone();
198 slice[ij + 1] = e;
199
200 i += 1;
201 j += 1;
202 }
203 Ordering::Greater => {
204 slice[i + j] = slice[midj].clone();
205 j += 1;
206 }
207 }
208 }
209}
210
211#[cfg(test)]
212mod tests {
213 use super::bubble;
214 use super::merge;
215 use super::quick;
216 use super::test;
217
218 #[test]
219 fn test_test() {
220 assert!(test(&[0, 3, 4, 10, 12]));
222 assert!(!test(&[6, 2, 1, 10, -2]));
223 }
224
225 #[test]
226 fn bubble_test() {
227 let mut data = [4, 2, 1, 8, 7, 9, -11];
228 bubble(&mut data);
229 assert_eq!(data, [-11, 1, 2, 4, 7, 8, 9]);
230 }
231
232 #[test]
233 fn quick_test() {
234 let mut data = [6, 7, 3, 5, 4, -12];
235 quick(&mut data);
236 assert_eq!(data, [-12, 3, 4, 5, 6, 7]);
237 }
238
239 #[test]
240 fn merge_test() {
241 let mut data1 = [6, 1, 2, 99, -1, 13, 7, 1];
242 let mut data2 = [5, 7, 11, -1, 2, 3];
243 let mut data3 = [11, 16, 20, 12, 13, 15];
244
245 merge(&mut data1);
246 merge(&mut data2);
247 merge(&mut data3);
248
249 assert_eq!(data1, [-1, 1, 1, 2, 6, 7, 13, 99]);
250 assert_eq!(data2, [-1, 2, 3, 5, 7, 11]);
251 assert_eq!(data3, [11, 12, 13, 15, 16, 20]);
252 }
253}