Skip to content

Commit bbc60e4

Browse files
authored
feat: add topological sorting (rust-lang#307)
1 parent 48acede commit bbc60e4

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ These are for demonstration purposes only.
3737
- [x] [Bellman-Ford](./src/graph/bellman_ford.rs)
3838
- [x] [Prufer Code](./src/graph/prufer_code.rs)
3939
- [x] [Lowest Common Ancestor](./src/graph/lowest_common_ancestor.rs)
40+
- [x] [Topological sorting](./src/graph/topological_sort.rs)
4041

4142
## [Math](./src/math)
4243
- [x] [Baby-Step Giant-Step Algorithm](./src/math/baby_step_giant_step.rs)

src/graph/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod lowest_common_ancestor;
99
mod minimum_spanning_tree;
1010
mod prim;
1111
mod prufer_code;
12+
mod topological_sort;
1213

1314
pub use self::bellman_ford::bellman_ford;
1415
pub use self::breadth_first_search::breadth_first_search;
@@ -21,3 +22,4 @@ pub use self::lowest_common_ancestor::{LowestCommonAncestorOffline, LowestCommon
2122
pub use self::minimum_spanning_tree::kruskal;
2223
pub use self::prim::{prim, prim_with_start};
2324
pub use self::prufer_code::{prufer_decode, prufer_encode};
25+
pub use self::topological_sort::topological_sort;

src/graph/topological_sort.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use std::collections::{BTreeMap, VecDeque};
2+
3+
type Graph<V, E> = BTreeMap<V, Vec<(V, E)>>;
4+
5+
/// returns topological sort of the graph using Kahn's algorithm
6+
pub fn topological_sort<V: Ord + Copy, E: Ord>(graph: &Graph<V, E>) -> Vec<V> {
7+
let mut visited = BTreeMap::new();
8+
let mut degree = BTreeMap::new();
9+
for u in graph.keys() {
10+
degree.insert(*u, 0);
11+
for (v, _) in graph.get(u).unwrap() {
12+
let entry = degree.entry(*v).or_insert(0);
13+
*entry += 1;
14+
}
15+
}
16+
let mut queue = VecDeque::new();
17+
for (u, d) in degree.iter() {
18+
if *d == 0 {
19+
queue.push_back(*u);
20+
visited.insert(*u, true);
21+
}
22+
}
23+
let mut ret = Vec::new();
24+
while let Some(u) = queue.pop_front() {
25+
ret.push(u);
26+
if let Some(from_u) = graph.get(&u) {
27+
for (v, _) in from_u {
28+
*degree.get_mut(v).unwrap() -= 1;
29+
if *degree.get(v).unwrap() == 0 {
30+
queue.push_back(*v);
31+
visited.insert(*v, true);
32+
}
33+
}
34+
}
35+
}
36+
ret
37+
}
38+
39+
#[cfg(test)]
40+
mod tests {
41+
use std::collections::BTreeMap;
42+
43+
use super::{topological_sort, Graph};
44+
fn add_edge<V: Ord + Copy, E: Ord>(graph: &mut Graph<V, E>, from: V, to: V, weight: E) {
45+
let edges = graph.entry(from).or_insert(Vec::new());
46+
edges.push((to, weight));
47+
}
48+
49+
#[test]
50+
fn it_works() {
51+
let mut graph = BTreeMap::new();
52+
add_edge(&mut graph, 1, 2, 1);
53+
add_edge(&mut graph, 1, 3, 1);
54+
add_edge(&mut graph, 2, 3, 1);
55+
add_edge(&mut graph, 3, 4, 1);
56+
add_edge(&mut graph, 4, 5, 1);
57+
add_edge(&mut graph, 5, 6, 1);
58+
add_edge(&mut graph, 6, 7, 1);
59+
60+
assert_eq!(topological_sort(&graph), vec![1, 2, 3, 4, 5, 6, 7]);
61+
}
62+
}

0 commit comments

Comments
 (0)