rust_igraph/algorithms/properties/
is_star.rs1use crate::algorithms::paths::dijkstra::DijkstraMode;
11use crate::algorithms::properties::is_tree::is_tree;
12use crate::core::{Graph, IgraphResult};
13
14pub fn is_star(graph: &Graph) -> IgraphResult<bool> {
44 if graph.is_directed() {
45 return Ok(false);
46 }
47
48 let n = graph.vcount();
49 if n == 0 {
50 return Ok(false);
51 }
52 if n == 1 {
53 return Ok(true);
54 }
55
56 if is_tree(graph, DijkstraMode::All)?.is_none() {
57 return Ok(false);
58 }
59
60 let n_minus_1 = n - 1;
63 let mut found_center = false;
64 for v in 0..n {
65 let d = graph.degree(v)?;
66 if d == n_minus_1 as usize {
67 found_center = true;
68 } else if d != 1 {
69 return Ok(false);
70 }
71 }
72
73 Ok(found_center)
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn empty_graph() {
82 let g = Graph::with_vertices(0);
83 assert!(!is_star(&g).unwrap());
84 }
85
86 #[test]
87 fn single_vertex() {
88 let g = Graph::with_vertices(1);
89 assert!(is_star(&g).unwrap());
90 }
91
92 #[test]
93 fn single_edge() {
94 let mut g = Graph::with_vertices(2);
95 g.add_edge(0, 1).unwrap();
96 assert!(is_star(&g).unwrap());
97 }
98
99 #[test]
100 fn k13() {
101 let mut g = Graph::with_vertices(4);
102 g.add_edge(0, 1).unwrap();
103 g.add_edge(0, 2).unwrap();
104 g.add_edge(0, 3).unwrap();
105 assert!(is_star(&g).unwrap());
106 }
107
108 #[test]
109 fn k14() {
110 let mut g = Graph::with_vertices(5);
111 for i in 1..5u32 {
112 g.add_edge(0, i).unwrap();
113 }
114 assert!(is_star(&g).unwrap());
115 }
116
117 #[test]
118 fn k17_center_not_zero() {
119 let mut g = Graph::with_vertices(8);
121 for i in 0..8u32 {
122 if i != 3 {
123 g.add_edge(3, i).unwrap();
124 }
125 }
126 assert!(is_star(&g).unwrap());
127 }
128
129 #[test]
130 fn path_p4_not_star() {
131 let mut g = Graph::with_vertices(4);
132 g.add_edge(0, 1).unwrap();
133 g.add_edge(1, 2).unwrap();
134 g.add_edge(2, 3).unwrap();
135 assert!(!is_star(&g).unwrap());
136 }
137
138 #[test]
139 fn triangle_not_star() {
140 let mut g = Graph::with_vertices(3);
141 g.add_edge(0, 1).unwrap();
142 g.add_edge(1, 2).unwrap();
143 g.add_edge(2, 0).unwrap();
144 assert!(!is_star(&g).unwrap());
145 }
146
147 #[test]
148 fn caterpillar_not_star() {
149 let mut g = Graph::with_vertices(5);
150 g.add_edge(0, 1).unwrap();
151 g.add_edge(1, 2).unwrap();
152 g.add_edge(2, 3).unwrap();
153 g.add_edge(1, 4).unwrap();
154 assert!(!is_star(&g).unwrap());
155 }
156
157 #[test]
158 fn directed_returns_false() {
159 let mut g = Graph::new(4, true).unwrap();
160 g.add_edge(0, 1).unwrap();
161 g.add_edge(0, 2).unwrap();
162 g.add_edge(0, 3).unwrap();
163 assert!(!is_star(&g).unwrap());
164 }
165
166 #[test]
167 fn disconnected_not_star() {
168 let mut g = Graph::with_vertices(4);
169 g.add_edge(0, 1).unwrap();
170 assert!(!is_star(&g).unwrap());
171 }
172
173 #[test]
174 fn two_isolated_not_star() {
175 let g = Graph::with_vertices(2);
176 assert!(!is_star(&g).unwrap());
177 }
178}