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 4c3cddc

Browse files
committed
misc.rs -> order.rs, with mergesort
1 parent b7b756b commit 4c3cddc

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

‎README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@ Rather than try to persuade you with words, this repository aims to show by exam
4545

4646
- [Basic graph representations](src/graph/mod.rs): adjacency lists, disjoint set union
4747
- [Elementary graph algorithms](src/graph/util.rs): minimum spanning tree, Euler path, Dijkstra's algorithm, DFS iteration
48-
- [Network flows](src/graph/flow.rs): Dinic's blocking flow, Hopcroft-Karp bipartite matching, min cost max flow
4948
- [Connected components](src/graph/connectivity.rs): 2-edge-, 2-vertex- and strongly connected components, bridges, articulation points, topological sort, 2-SAT
50-
- [Associative range query](src/range_query): known colloquially as *segtrees*, as well as Mo's query square root decomposition
49+
- [Network flows](src/graph/flow.rs): Dinic's blocking flow, Hopcroft-Karp bipartite matching, min cost max flow
5150
- [Number theory](src/math/mod.rs): canonical solution to Bezout's identity, Miller's primality test
52-
- [Arithmetic](src/math/num.rs): rational and complex numbers, linear algebra, safe modular arithmetic
5351
- [FFT](src/math/fft.rs): fast Fourier transform, number theoretic transform, convolution
52+
- [Arithmetic](src/math/num.rs): rational and complex numbers, linear algebra, safe modular arithmetic
53+
- [Ordering algorithms](src/order.rs): binary search, mergesort, coordinate compression, amortized convex hull trick
54+
- [Associative range query](src/range_query): static and dynamic ARQ trees (a.k.a. segtrees), Mo's query square root decomposition
5455
- [Scanner](src/scanner.rs): utility for reading input data ergonomically
5556
- [String processing](src/string_proc.rs): Knuth-Morris-Pratt and Aho-Corasick string matching, suffix array, Manacher's linear-time palindrome search
56-
-[Miscellaneous algorithms](src/misc.rs): slice binary search, coordinate compression, convex hull trick with sqrt decomposition
57+

‎src/graph/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! All methods will panic if given an out-of-bounds element index.
66
pub mod connectivity;
77
pub mod flow;
8-
mod util;
8+
pubmod util;
99

1010
/// Represents a union of disjoint sets. Each set's elements are arranged in a
1111
/// tree, whose root is the set's representative.

‎src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Algorithms Cookbook in Rust.
22
pub mod graph;
33
pub mod math;
4-
pub mod misc;
4+
pub mod order;
55
pub mod range_query;
66
pub mod scanner;
77
pub mod string_proc;

‎src/misc.rs renamed to ‎src/order.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,23 @@ pub fn asserting_cmp<T: PartialOrd>(a: &T, b: &T) -> std::cmp::Ordering {
55
a.partial_cmp(b).expect("Comparing incomparable elements")
66
}
77

8-
/// Assuming slice is totally ordered and sorted, returns the minimum i for which
8+
/// Assuming slice is sorted and totally ordered, returns the minimum i for which
99
/// slice[i] >= key, or slice.len() if no such i exists
1010
pub fn slice_lower_bound<T: PartialOrd>(slice: &[T], key: &T) -> usize {
1111
slice
1212
.binary_search_by(|x| asserting_cmp(x, key).then(std::cmp::Ordering::Greater))
1313
.unwrap_err()
1414
}
1515

16-
/// Assuming slice is totally ordered and sorted, returns the minimum i for which
16+
/// Assuming slice is sorted and totally ordered, returns the minimum i for which
1717
/// slice[i] > key, or slice.len() if no such i exists
1818
pub fn slice_upper_bound<T: PartialOrd>(slice: &[T], key: &T) -> usize {
1919
slice
2020
.binary_search_by(|x| asserting_cmp(x, key).then(std::cmp::Ordering::Less))
2121
.unwrap_err()
2222
}
2323

24-
/// Merge two sorted collections into one
24+
/// Merge two sorted and totally ordered collections into one
2525
pub fn merge_sorted<T: PartialOrd>(
2626
i1: impl IntoIterator<Item = T>,
2727
i2: impl IntoIterator<Item = T>,
@@ -35,6 +35,16 @@ pub fn merge_sorted<T: PartialOrd>(
3535
merged
3636
}
3737

38+
/// A stable sort
39+
pub fn merge_sort<T: Ord>(mut v: Vec<T>) -> Vec<T> {
40+
if v.len() < 2 {
41+
v
42+
} else {
43+
let v2 = v.split_off(v.len() / 2);
44+
merge_sorted(merge_sort(v), merge_sort(v2))
45+
}
46+
}
47+
3848
/// A simple data structure for coordinate compression
3949
pub struct SparseIndex {
4050
coords: Vec<i64>,
@@ -58,9 +68,9 @@ impl SparseIndex {
5868
/// Represents a maximum (upper envelope) of a collection of linear functions of a variable,
5969
/// evaluated using the convex hull trick with square root decomposition.
6070
pub struct PiecewiseLinearFn {
71+
recent_lines: Vec<(f64, f64)>,
6172
sorted_lines: Vec<(f64, f64)>,
6273
intersections: Vec<f64>,
63-
recent_lines: Vec<(f64, f64)>,
6474
merge_threshold: usize,
6575
}
6676

@@ -70,9 +80,9 @@ impl PiecewiseLinearFn {
7080
/// any threshold less than N (e.g., 0) yields O(N + Q log N) time complexity.
7181
pub fn with_merge_threshold(merge_threshold: usize) -> Self {
7282
Self {
83+
recent_lines: vec![],
7384
sorted_lines: vec![],
7485
intersections: vec![],
75-
recent_lines: vec![],
7686
merge_threshold,
7787
}
7888
}
@@ -155,6 +165,15 @@ mod test {
155165
assert_eq!(merge_sorted(vals1, vals2), vals_merged);
156166
}
157167

168+
#[test]
169+
fn test_merge_sort() {
170+
let unsorted = vec![8, -5, 1, 4, -3, 4];
171+
let sorted = vec![-5, -3, 1, 4, 4, 8];
172+
173+
assert_eq!(merge_sort(unsorted), sorted);
174+
assert_eq!(merge_sort(sorted.clone()), sorted);
175+
}
176+
158177
#[test]
159178
fn test_coord_compress() {
160179
let mut coords = vec![16, 99, 45, 18];

0 commit comments

Comments
(0)

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