├── .gitignore ├── README.md ├── Cargo.toml ├── LICENSE └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | *~ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # simple-graph 2 | 3 | A (very) simple graph library. 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | 3 | name = "simple-graph" 4 | version = "0.0.1" 5 | authors = ["Niko Matsakis "] 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub struct Graph { 2 | nodes: Vec, 3 | edges: Vec, 4 | } 5 | 6 | pub type NodeIndex = usize; 7 | 8 | pub struct NodeData { 9 | first_outgoing_edge: Option, 10 | } 11 | 12 | pub type EdgeIndex = usize; 13 | 14 | pub struct EdgeData { 15 | target: NodeIndex, 16 | next_outgoing_edge: Option 17 | } 18 | 19 | impl Graph { 20 | pub fn new() -> Graph { 21 | Graph { nodes: Vec::new(), 22 | edges: Vec::new(), } 23 | } 24 | 25 | fn add_node(&mut self) -> NodeIndex { 26 | let index = self.nodes.len(); 27 | self.nodes.push(NodeData { first_outgoing_edge: None }); 28 | index 29 | } 30 | 31 | fn add_edge(&mut self, source: NodeIndex, target: NodeIndex) { 32 | let edge_index = self.edges.len(); 33 | let node_data = &mut self.nodes[source]; 34 | self.edges.push(EdgeData { 35 | target: target, 36 | next_outgoing_edge: node_data.first_outgoing_edge 37 | }); 38 | node_data.first_outgoing_edge = Some(edge_index); 39 | } 40 | 41 | fn successors(&self, source: NodeIndex) -> Successors { 42 | let first_outgoing_edge = self.nodes[source].first_outgoing_edge; 43 | Successors { graph: self, current_edge_index: first_outgoing_edge } 44 | } 45 | } 46 | 47 | pub struct Successors<'graph> { 48 | graph: &'graph Graph, 49 | current_edge_index: Option, 50 | } 51 | 52 | impl<'graph> Iterator for Successors<'graph> { 53 | type Item = NodeIndex; 54 | 55 | fn next(&mut self) -> Option { 56 | match self.current_edge_index { 57 | None => None, 58 | Some(edge_num) => { 59 | let edge = &self.graph.edges[edge_num]; 60 | self.current_edge_index = edge.next_outgoing_edge; 61 | Some(edge.target) 62 | } 63 | } 64 | } 65 | } 66 | 67 | 68 | mod test { 69 | use super::*; 70 | 71 | #[test] 72 | fn example() { 73 | 74 | // N0 ---E0---> N1 ---E1---> 2 75 | // | ^ 76 | // E2 | 77 | // | | 78 | // v | 79 | // N3 ----------E3-----------+ 80 | 81 | let mut graph = Graph::new(); 82 | 83 | let n0 = graph.add_node(); 84 | let n1 = graph.add_node(); 85 | let n2 = graph.add_node(); 86 | let n3 = graph.add_node(); 87 | 88 | graph.add_edge(n0, n1); // e0 89 | graph.add_edge(n1, n2); // e1 90 | graph.add_edge(n0, n3); // e2 91 | graph.add_edge(n3, n2); // e3 92 | 93 | let successors: Vec = graph.successors(n0).collect(); 94 | assert_eq!(&successors[..], &[n3, n1]); 95 | } 96 | } 97 | --------------------------------------------------------------------------------