From a250bde626be294b801e13a842ee9d67af71e9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Wed, 22 Apr 2026 14:49:07 +0200 Subject: [PATCH] Add DijkstraResult return type instead of unnamed tuple --- src/algorithms.rs | 26 ++++++++++++++++---------- tests/dijkstra.rs | 32 ++++++++++++++++---------------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/algorithms.rs b/src/algorithms.rs index 3bb54e9..7b65faf 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -21,19 +21,25 @@ impl Ord for DistanceOrderedVertex { } } -// TODO: Maybe introduce a return struct type for Dijkstra's algorithm? +pub struct DijkstraResult { + pub distances: Vec>, + pub predecessors: Vec>, +} + // TODO: Maybe variant of Dijkstra's algorithm without predecessors? // TODO: Replace Vec storage with VertexMap, this should make the bound on G::Vertex here obsolete. -pub fn dijkstra(graph: &G, source: G::Vertex) -> (Vec>, Vec>) +pub fn dijkstra(graph: &G, source: G::Vertex) -> DijkstraResult where G: GraphTopology, G::Vertex: Into, { - let mut distances = vec![None; graph.vertex_count()]; - let mut predecessors = vec![None; graph.vertex_count()]; + let mut result = DijkstraResult { + distances: vec![None; graph.vertex_count()], + predecessors: vec![None; graph.vertex_count()], + }; let mut heap = BinaryHeap::new(); - distances[source.into()] = Some(0); + result.distances[source.into()] = Some(0); heap.push(DistanceOrderedVertex { vertex: source, distance: 0, @@ -43,14 +49,14 @@ where for neighbor in graph.neighbors(v.vertex) { // TODO: Add a way to provide custom edge weights for Dijkstra's algorithm. let edge_weight = 1; - let new_distance = distances[v.vertex.into()].unwrap() + edge_weight; - if match distances[neighbor.into()] { + let new_distance = result.distances[v.vertex.into()].unwrap() + edge_weight; + if match result.distances[neighbor.into()] { None => true, Some(old_distance) if old_distance > new_distance => true, _ => false, } { - distances[neighbor.into()] = Some(new_distance); - predecessors[neighbor.into()] = Some(v.vertex); + result.distances[neighbor.into()] = Some(new_distance); + result.predecessors[neighbor.into()] = Some(v.vertex); heap.push(DistanceOrderedVertex { vertex: neighbor, distance: new_distance, @@ -58,5 +64,5 @@ where } } } - (distances, predecessors) + result } diff --git a/tests/dijkstra.rs b/tests/dijkstra.rs index 37196da..f4dc9ad 100644 --- a/tests/dijkstra.rs +++ b/tests/dijkstra.rs @@ -6,24 +6,24 @@ use grapherity::traits::GraphTopology; fn dijkstra_single_vertex() { let mut graph = AppendGraph::new(); let v1 = graph.add_vertex(); - let (distances, predecessors) = algorithms::dijkstra(&graph, v1); + let result = algorithms::dijkstra(&graph, v1); assert_eq!( - distances.len(), + result.distances.len(), 1, "distances count must equal vertex count" ); assert_eq!( - predecessors.len(), + result.predecessors.len(), 1, "predecessors count must equal vertex count" ); assert_eq!( - distances[0], + result.distances[0], Some(0), "unexpected distance of source vertex" ); assert_eq!( - predecessors[0], None, + result.predecessors[0], None, "unexpected predecessor of source vertex", ); } @@ -33,23 +33,23 @@ fn dijkstra_disconnected() { let mut graph = AppendGraph::new(); let v1 = graph.add_vertex(); graph.add_vertex(); - let (distances, predecessors) = algorithms::dijkstra(&graph, v1); + let result = algorithms::dijkstra(&graph, v1); assert_eq!( - distances.len(), + result.distances.len(), 2, "distances count must equal vertex count" ); assert_eq!( - predecessors.len(), + result.predecessors.len(), 2, "predecessors count must equal vertex count" ); assert_eq!( - distances[1], None, + result.distances[1], None, "unexpected distance of disconnected vertex" ); assert_eq!( - predecessors[0], None, + result.predecessors[0], None, "unexpected predecessor of disconnected vertex", ); } @@ -57,7 +57,7 @@ fn dijkstra_disconnected() { #[test] fn dijkstra() { let (graph, vertices) = make_test_graph(); - let (distances, predecessors) = algorithms::dijkstra(&graph, vertices[0]); + let result = algorithms::dijkstra(&graph, vertices[0]); let expected_distances_from_v0 = [ Some(0), Some(1), @@ -83,25 +83,25 @@ fn dijkstra() { vec![Some(vertices[5]), Some(vertices[6]), Some(vertices[7])], ]; assert_eq!( - distances.len(), + result.distances.len(), graph.vertex_count(), "distances count must equal vertex count" ); assert_eq!( - predecessors.len(), + result.predecessors.len(), graph.vertex_count(), "predecessors count must equal vertex count" ); for i in 0..graph.vertex_count() { assert_eq!( - distances[i], expected_distances_from_v0[i], + result.distances[i], expected_distances_from_v0[i], "unexpected distance from {:?} to {:?}", vertices[0], vertices[i] ); assert!( - expected_predecessors_from_v0[i].contains(&predecessors[i]), + expected_predecessors_from_v0[i].contains(&result.predecessors[i]), "unexpected predecessor {:?} of {:?}", - predecessors[i], + result.predecessors[i], vertices[i] ); }