implement graph

This commit is contained in:
cy 2025-01-13 22:49:04 -05:00
commit 268daf6c93
5 changed files with 118 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

7
Cargo.lock generated Normal file
View 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
View file

@ -0,0 +1,6 @@
[package]
name = "skiena"
version = "0.1.0"
edition = "2021"
[dependencies]

80
src/graph.rs Normal file
View 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
View 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();
}