rust_algorithms/graph/
core.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct Edge {
6 pub to: usize,
8 pub weight: i64,
10}
11
12#[derive(Debug, Clone)]
33pub struct Graph {
34 adj: Vec<Vec<Edge>>,
35 directed: bool,
36 edge_count: usize,
37}
38
39impl Graph {
40 pub fn new_undirected(n: usize) -> Self {
42 Self {
43 adj: vec![Vec::new(); n],
44 directed: false,
45 edge_count: 0,
46 }
47 }
48
49 pub fn new_directed(n: usize) -> Self {
51 Self {
52 adj: vec![Vec::new(); n],
53 directed: true,
54 edge_count: 0,
55 }
56 }
57
58 pub fn add_edge(&mut self, from: usize, to: usize, weight: i64) {
63 assert!(
64 from < self.adj.len() && to < self.adj.len(),
65 "tugun indeksi chegaradan tashqarida"
66 );
67 self.adj[from].push(Edge { to, weight });
68 if !self.directed && from != to {
69 self.adj[to].push(Edge { to: from, weight });
70 }
71 self.edge_count += 1;
72 }
73
74 pub fn add_unweighted_edge(&mut self, from: usize, to: usize) {
76 self.add_edge(from, to, 1);
77 }
78
79 pub fn neighbors(&self, node: usize) -> &[Edge] {
81 &self.adj[node]
82 }
83
84 pub fn has_edge(&self, from: usize, to: usize) -> bool {
86 self.adj[from].iter().any(|e| e.to == to)
87 }
88
89 pub fn degree(&self, node: usize) -> usize {
91 self.adj[node].len()
92 }
93
94 pub fn node_count(&self) -> usize {
96 self.adj.len()
97 }
98
99 pub fn edge_count(&self) -> usize {
101 self.edge_count
102 }
103
104 pub fn is_directed(&self) -> bool {
106 self.directed
107 }
108
109 pub fn all_edges(&self) -> Vec<(usize, usize, i64)> {
112 let mut out = Vec::with_capacity(self.edge_count);
113 for (from, qirralar) in self.adj.iter().enumerate() {
114 for e in qirralar {
115 if self.directed || from <= e.to {
116 out.push((from, e.to, e.weight));
117 }
118 }
119 }
120 out
121 }
122
123 pub fn reversed(&self) -> Graph {
127 let mut g = if self.directed {
128 Graph::new_directed(self.node_count())
129 } else {
130 return self.clone();
131 };
132 for (from, qirralar) in self.adj.iter().enumerate() {
133 for e in qirralar {
134 g.add_edge(e.to, from, e.weight);
135 }
136 }
137 g
138 }
139}
140
141#[cfg(test)]
142mod tests {
143 use super::*;
144
145 #[test]
146 fn yonaltirilmagan_ikki_tomonlama() {
147 let mut g = Graph::new_undirected(3);
148 g.add_edge(0, 1, 7);
149 assert!(g.has_edge(0, 1));
150 assert!(g.has_edge(1, 0));
151 assert_eq!(g.degree(0), 1);
152 assert_eq!(g.degree(1), 1);
153 assert_eq!(g.edge_count(), 1);
154 }
155
156 #[test]
157 fn yonaltirilgan_bir_tomonlama() {
158 let mut g = Graph::new_directed(3);
159 g.add_edge(0, 1, 1);
160 assert!(g.has_edge(0, 1));
161 assert!(!g.has_edge(1, 0));
162 assert_eq!(g.degree(1), 0);
163 }
164
165 #[test]
166 fn barcha_qirralar() {
167 let mut g = Graph::new_undirected(4);
168 g.add_edge(0, 1, 5);
169 g.add_edge(2, 3, 2);
170 let mut e = g.all_edges();
171 e.sort();
172 assert_eq!(e, vec![(0, 1, 5), (2, 3, 2)]);
173 }
174
175 #[test]
176 fn teskarilash() {
177 let mut g = Graph::new_directed(3);
178 g.add_edge(0, 1, 1);
179 g.add_edge(1, 2, 2);
180 let r = g.reversed();
181 assert!(r.has_edge(1, 0));
182 assert!(r.has_edge(2, 1));
183 assert!(!r.has_edge(0, 1));
184 }
185
186 #[test]
187 fn ozini_ozi_bogash() {
188 let mut g = Graph::new_undirected(2);
189 g.add_edge(0, 0, 1); assert_eq!(g.degree(0), 1);
191 assert!(g.has_edge(0, 0));
192 }
193}