From 2e72de2281034b69a7133533e12713f4243cd020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Sat, 4 Oct 2025 22:23:08 +0200 Subject: [PATCH] Add experimental Graph implementation --- src/main.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/main.rs b/src/main.rs index e7a11a9..bff4b7a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,76 @@ +#[derive(Copy, Clone, PartialEq, Eq)] +struct Vertex(usize); + +#[derive(Copy, Clone, PartialEq, Eq)] +struct Incidence(usize); + +struct VertexIncidenceHeader { + incidence_count: usize, + first_incidence: Option, +} + +// TODO: Visibility of Graph members. +struct Graph { + // TODO: Index 'vertex_incidence_headers' by a 'Vertex' instead of 'Vertex.0'? + vertex_incidence_headers: Vec, + next_incidences: Vec>, + incidence_vertices: Vec, +} + +// TODO: Add iterator of vertex neighbors, see 'fn add_adjacent()'. +impl Graph { + fn vertex_count(&self) -> usize { + self.vertex_incidence_headers.len() + } + + fn edge_count(&self) -> usize { + self.next_incidences.len() / 2 + } + + fn degree(&self, v: Vertex) -> usize { + self.vertex_incidence_headers[v.0].incidence_count + } + + // TODO: 'fn are_adjacent()' could probably be done with a neighbor vertex iterator. + fn are_adjacent(&self, v1: Vertex, v2: Vertex) -> bool { + let Some(next) = self.vertex_incidence_headers[v1.0].first_incidence else { + return false; + }; + loop { + if self.incidence_vertices[next.0] == v2 { + return true; + } + let Some(next) = self.next_incidences[next.0] else { + return false; + }; + } + } + + // TODO: 'fn add_vertex()' should not be publicly accessible for all graph implementations. + // TODO: 'fn add_vertex()' needs variants for custom vertex data. + fn add_vertex(&mut self) -> Vertex { + self.vertex_incidence_headers.push(VertexIncidenceHeader { + incidence_count: 0, + first_incidence: None, + }); + Vertex(self.vertex_incidence_headers.len() - 1) + } + + // TODO: 'fn add_edge()' should not be publicly accessible for all graph implementations. + // TODO: 'fn add_edge()' needs variants for custom edge data. + fn add_edge(&mut self, v1: Vertex, v2: Vertex) { + self.add_incidence(v1, v2); + self.add_incidence(v2, v1); + } + + fn add_incidence(&mut self, v1: Vertex, v2: Vertex) { + self.incidence_vertices.push(v2); + self.next_incidences.push(self.vertex_incidence_headers[v1.0].first_incidence.take()); + self.vertex_incidence_headers[v1.0].incidence_count += 1; + self.vertex_incidence_headers[v1.0].first_incidence = Some(Incidence(self.incidence_vertices.len() - 1)); + } +} + fn main() { println!("Hello, world!"); }