Combine next_incidences and incidence_vertices of Graph into one, and rename incidence_headers to vertices

This commit is contained in:
2026-03-19 21:21:52 +01:00
parent c5a0f2a3f6
commit 489ed6d506
+25 -21
View File
@@ -10,6 +10,11 @@ struct VertexIncidenceHeader {
first_incidence: Option<Incidence>, first_incidence: Option<Incidence>,
} }
struct IncidenceEntry {
next: Option<Incidence>,
neighbor: Vertex,
}
pub struct VertexNeighborIterator<'a> { pub struct VertexNeighborIterator<'a> {
graph: &'a Graph, graph: &'a Graph,
incidence: Option<Incidence>, incidence: Option<Incidence>,
@@ -20,8 +25,9 @@ impl<'a> Iterator for VertexNeighborIterator<'a> {
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let incidence = self.incidence?; let incidence = self.incidence?;
self.incidence = self.graph.next_incidences[incidence.0]; let entry = &self.graph.incidences[incidence.0];
Some(self.graph.incidence_vertices[incidence.0]) self.incidence = entry.next;
Some(entry.neighbor)
} }
} }
@@ -32,30 +38,28 @@ impl<'a> Iterator for VertexNeighborIterator<'a> {
// TODO: Add iterator of edges. // TODO: Add iterator of edges.
pub struct Graph { pub struct Graph {
// TODO: Index 'incidence_headers' by a 'Vertex' instead of 'Vertex.0'? // TODO: Index 'incidence_headers' by a 'Vertex' instead of 'Vertex.0'?
incidence_headers: Vec<VertexIncidenceHeader>, vertices: Vec<VertexIncidenceHeader>,
next_incidences: Vec<Option<Incidence>>, incidences: Vec<IncidenceEntry>,
incidence_vertices: Vec<Vertex>,
} }
impl Graph { impl Graph {
pub fn new() -> Graph { pub fn new() -> Graph {
Graph { Graph {
incidence_headers: vec![], vertices: vec![],
next_incidences: vec![], incidences: vec![],
incidence_vertices: vec![],
} }
} }
pub fn vertex_count(&self) -> usize { pub fn vertex_count(&self) -> usize {
self.incidence_headers.len() self.vertices.len()
} }
pub fn edge_count(&self) -> usize { pub fn edge_count(&self) -> usize {
self.next_incidences.len() / 2 self.incidences.len() / 2
} }
pub fn degree(&self, v: Vertex) -> usize { pub fn degree(&self, v: Vertex) -> usize {
self.incidence_headers[v.0].incidence_count self.vertices[v.0].incidence_count
} }
pub fn are_adjacent(&self, v1: Vertex, v2: Vertex) -> bool { pub fn are_adjacent(&self, v1: Vertex, v2: Vertex) -> bool {
@@ -64,11 +68,11 @@ impl Graph {
// TODO: 'fn add_vertex()' needs variants for custom vertex data. // TODO: 'fn add_vertex()' needs variants for custom vertex data.
pub fn add_vertex(&mut self) -> Vertex { pub fn add_vertex(&mut self) -> Vertex {
self.incidence_headers.push(VertexIncidenceHeader { self.vertices.push(VertexIncidenceHeader {
incidence_count: 0, incidence_count: 0,
first_incidence: None, first_incidence: None,
}); });
Vertex(self.incidence_headers.len() - 1) Vertex(self.vertices.len() - 1)
} }
// TODO: 'fn add_edge()' needs variants for custom edge data. // TODO: 'fn add_edge()' needs variants for custom edge data.
@@ -78,22 +82,22 @@ impl Graph {
} }
fn add_incidence(&mut self, v1: Vertex, v2: Vertex) { fn add_incidence(&mut self, v1: Vertex, v2: Vertex) {
self.incidence_vertices.push(v2); self.incidences.push(IncidenceEntry {
self.next_incidences next: self.vertices[v1.0].first_incidence.take(),
.push(self.incidence_headers[v1.0].first_incidence.take()); neighbor: v2,
self.incidence_headers[v1.0].incidence_count += 1; });
self.incidence_headers[v1.0].first_incidence = self.vertices[v1.0].incidence_count += 1;
Some(Incidence(self.incidence_vertices.len() - 1)); self.vertices[v1.0].first_incidence = Some(Incidence(self.incidences.len() - 1));
} }
pub fn vertices(&self) -> impl Iterator<Item = Vertex> { pub fn vertices(&self) -> impl Iterator<Item = Vertex> {
(0..self.incidence_headers.len()).map(Vertex) (0..self.vertices.len()).map(Vertex)
} }
pub fn neighbors(&self, v: Vertex) -> impl Iterator<Item = Vertex> { pub fn neighbors(&self, v: Vertex) -> impl Iterator<Item = Vertex> {
VertexNeighborIterator { VertexNeighborIterator {
graph: self, graph: self,
incidence: self.incidence_headers[v.0].first_incidence, incidence: self.vertices[v.0].first_incidence,
} }
} }
} }