implement graph
This commit is contained in:
commit
268daf6c93
5 changed files with 118 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "skiena"
|
||||
version = "0.1.0"
|
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "skiena"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
80
src/graph.rs
Normal file
80
src/graph.rs
Normal file
|
@ -0,0 +1,80 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
const MAXV: usize = 1000;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Edgenode {
|
||||
#[allow(unused)]
|
||||
weight: i32, // Edge weight, if any
|
||||
|
||||
y: i32, // Adjacency info
|
||||
next: Option<Rc<Edgenode>>, // next edge in list
|
||||
}
|
||||
|
||||
pub struct Graph {
|
||||
edges: Vec<Option<Rc<Edgenode>>>, // adjacency info
|
||||
degree: Vec<i32>, // outdegree of each vertex
|
||||
nvertices: i32, // number of vertices in graph
|
||||
nedges: i32, // number of edges in graph
|
||||
directed: bool, // is the graph directed?
|
||||
}
|
||||
|
||||
impl Graph {
|
||||
pub fn new(directed: bool) -> Self {
|
||||
Self {
|
||||
nvertices: 0,
|
||||
nedges: 0,
|
||||
directed,
|
||||
degree: vec![0; MAXV],
|
||||
edges: vec![None; MAXV],
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_edge(&mut self, x: usize, y: i32, directed: bool) {
|
||||
let p = Rc::new(Edgenode {
|
||||
y,
|
||||
weight: 0,
|
||||
next: self.edges[x].clone(),
|
||||
});
|
||||
self.edges[x] = Some(p);
|
||||
self.degree[x] += 1;
|
||||
if directed {
|
||||
self.nedges += 1;
|
||||
} else {
|
||||
self.insert_edge(y.try_into().unwrap(), x.try_into().unwrap(), true);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_graph(&self) {
|
||||
for i in 0..self.nvertices as usize {
|
||||
print!("{} -->", i);
|
||||
let mut p_opt = self.edges[i].clone();
|
||||
while let Some(p) = p_opt {
|
||||
print!(" {}", p.y);
|
||||
p_opt = p.next.clone();
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_graph(&mut self, data: String) {
|
||||
self._read_graph(data, self.directed);
|
||||
}
|
||||
|
||||
fn _read_graph(&mut self, data: String, directed: bool) {
|
||||
// reverse here so that we can pop() later
|
||||
let mut data_parsed: Vec<&str> = data.split(' ').rev().collect();
|
||||
|
||||
// The first two digits in `data` are `nvertices` and the total number of edges
|
||||
// between them
|
||||
self.nvertices = data_parsed.pop().unwrap().parse().expect("invalid int");
|
||||
let num_edges: i32 = data_parsed.pop().unwrap().parse().expect("invalid int");
|
||||
|
||||
// After that, parse edges as (x, y)
|
||||
for _ in 0..num_edges {
|
||||
let x: i32 = data_parsed.pop().unwrap().parse().unwrap();
|
||||
let y: i32 = data_parsed.pop().unwrap().parse().unwrap();
|
||||
self.insert_edge(x.try_into().unwrap(), y, directed);
|
||||
}
|
||||
}
|
||||
}
|
24
src/main.rs
Normal file
24
src/main.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
use crate::graph::Graph;
|
||||
|
||||
mod graph;
|
||||
|
||||
fn main() {
|
||||
let mut graph = Graph::new(true);
|
||||
let data = "5 14 \
|
||||
1 2 \
|
||||
1 5 \
|
||||
2 1 \
|
||||
2 5 \
|
||||
2 3 \
|
||||
2 4 \
|
||||
3 2 \
|
||||
3 4 \
|
||||
4 2 \
|
||||
4 5 \
|
||||
4 3 \
|
||||
5 4 \
|
||||
5 1 \
|
||||
5 2";
|
||||
graph.read_graph(data.to_string());
|
||||
graph.print_graph();
|
||||
}
|
Loading…
Add table
Reference in a new issue