Skip to content

Commit

Permalink
Merge pull request #41 from ghimiresdp/feature/kruskal
Browse files Browse the repository at this point in the history
Kruskal's algorithm
  • Loading branch information
ghimiresdp authored Oct 4, 2024
2 parents 15255f3 + 66042b5 commit 87b92a4
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 19 deletions.
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,13 @@ cargo test --bin huffman

1. [Activity Selection]
2. [Huffman Coding](algorithms/greedy/huffman_coding.rs) `cargo run --bin huffman`
3. [Krushkal's algorithm]
3. [Krushkal's algorithm](algorithms/greedy/kruskal.rs) `cargo run --bin kruskal`
4. [Prim's Algorithm]

### [2.4. Graph Algorithms](algorithms/graph/)

1. [Dijkstra's Algorithm]
2. [Bellman-Ford Algorithm]
3. [Floyd-Warshall Algorithm]
4. [Topological Sort]
5. [A* Search Algorithm]
5. [Dijkstra's Algorithm]
6. [Bellman-Ford Algorithm]
7. [Floyd-Warshall Algorithm]
8. [Topological Sort]
9. [A* Search Algorithm]

## [3. Design Patterns](./design-patterns/README.md)

Expand Down
4 changes: 4 additions & 0 deletions algorithms/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ path = "sorting/quick_sort.rs"
[[bin]]
name = "huffman"
path = "greedy/huffman_coding.rs"

[[bin]]
name = "kruskal"
path = "greedy/kruskal.rs"
17 changes: 7 additions & 10 deletions algorithms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,14 @@ List Of Algorithms are as follows:
7. [Counting Sort]
8. [Radix Sort]

### Greedy Algorithms
### Greedy and graph algorithms

1. [Activity Selection]
2. [Huffman Coding](greedy/huffman_coding.rs) `cargo run --bin huffman`
3. [Krushkal's algorithm]
3. [Krushkal's algorithm](greedy/kruskal.rs) `cargo run --bin kruskal`
4. [Prim's Algorithm]

### Graph Algorithms

1. [Dijkstra's Algorithm]
2. [Bellman-Ford Algorithm]
3. [Floyd-Warshall Algorithm]
4. [Topological Sort]
5. [A* Search Algorithm]
5. [Dijkstra's Algorithm]
6. [Bellman-Ford Algorithm]
7. [Floyd-Warshall Algorithm]
8. [Topological Sort]
9. [A* Search Algorithm]
168 changes: 168 additions & 0 deletions algorithms/greedy/kruskal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/// Kruskal's Algorithm
///
/// Kruskal's Algorithm is a minimum spanning tree algorithm also known as MST
/// algorithm. it takes a graph as input and finds the subset of the edges of
/// that graph which
/// - forms a tree that includes every vertex
/// - has minimum sum of weights among all the trees that can be formed from
/// - the graph.
///
/// It falls under the greedy algorithm.
///
/// ```
/// 8 7
/// (A)-------(B)-------(C)
/// / | | \ | \
/// 4/ | 2| \ | \ 9
/// / | | \ | \
/// (H) 11 (I) \4 |14 (D)
/// \ | / | \ | /
/// 8\ | 7 / 6| \ | /10
/// \ | / | \ | /
/// (G)-------(F)-------(E)
/// 1 2
///```
/// In the above figure, there are 9 vertices and 14 edes.
/// so the minimum spanning tree(MST) will be 9 -1 = 8 edges.
///
/// after finding the mst, the graph will be as follows:
/// ```
/// 7
/// (A) (B)-------(C)
/// / | \ \
/// 4/ 2| \ \ 9
/// / | \ \
/// (H) (I) \4 (D)
/// \ \
/// 8\ \
/// \ \
/// (G)-------(F)-------(E)
/// 1 2
///
/// steps:
/// 1. sort all the edges from low weight to high
/// 2. Take the edge with the lowest weight and add it to the spanning tree.
/// If the edge creates a cycle then reject the edge.
/// 3. keep adding edges until we reach all vertices.
///```
use std::collections::HashMap;

/// # Edge
///
/// This is a data structure that stores information about the source node,
/// destination node, and weight to travel to the destination node.
/// each point in the graph. Eg: A, B, etc is a vertex.one vertex connects to another

type Edge = (char, char, usize); // (from, to, weight)

fn find_parent(visited: &HashMap<char, char>, vertex: char) -> char {
print!("⛔ {vertex} -> ");
if visited.contains_key(&vertex) {
return find_parent(visited, *visited.get(&vertex).unwrap());
}
return vertex;
}

fn rank(a: char, b: char) -> (char, char) {
if a > b {
return (a, b);
} else {
return (b, a);
}
}

struct Graph {
edges: Vec<Edge>,
}
impl Graph {
fn new(edges: Vec<(char, char, usize)>) -> Self {
Self { edges }
}

fn sort_edges(&mut self) {
self.edges.sort_by(|a, b| a.2.cmp(&b.2));
}

fn find_mst(&mut self) -> Vec<Edge> {
// let mut graph = Graph::new(vec![]);
let mut edges = Vec::new();
let mut visited: HashMap<char, char> = HashMap::new();

// Step 1: sort all the edges by weight
self.sort_edges();
for (a, b, weight) in self.edges.iter() {
let (a, b) = rank(*a, *b);
let parent_a = find_parent(&visited, a);
println!("{parent_a}");
let parent_b = find_parent(&visited, b);
println!("{parent_b}");
if parent_a != parent_b {
if visited.contains_key(&a) && visited.contains_key(&b) {
let val_a = visited.get(&a).unwrap();
let val_b = visited.get(&b).unwrap();
if visited.contains_key(val_a) {
visited.insert(*val_b, b);
} else {
visited.insert(*val_a, a);
}
}
edges.push((a, b, *weight));
if visited.contains_key(&a) {
visited.insert(b, a);
println!("{}->{}", b, a);
} else {
visited.insert(a, b);
println!("{}->{}", a, b);
}
}
println!("===================================================");
}
return edges;
}
}

fn main() {
let mut graph = Graph::new(vec![
('A', 'B', 8),
('A', 'G', 11),
('A', 'H', 4),
('B', 'C', 7),
('B', 'E', 4),
('B', 'I', 2),
('C', 'D', 9),
('C', 'E', 14),
('D', 'E', 10),
('E', 'F', 2),
('F', 'G', 1),
('F', 'I', 6),
('G', 'H', 8),
('G', 'I', 7),
]);
let updated_edges = graph.find_mst();
println!("edges: {:?}", updated_edges)
}

#[cfg(test)]
mod tests {
use crate::Graph;

#[test]
fn test_1() {
let mut graph = Graph::new(vec![
('A', 'B', 3),
('B', 'C', 3),
('C', 'D', 5),
('D', 'A', 1),
('B', 'D', 2),
]);
let updated_edges = graph.find_mst();

assert_eq!(updated_edges.len(), 3);
// sometimes, due to ranking, the position of the first and second
// vertices of an edge may be interchanged.
assert_eq!(
updated_edges,
vec![('D', 'A', 1), ('D', 'B', 2), ('C', 'B', 3)]
)
}
}

0 comments on commit 87b92a4

Please sign in to comment.