package graphs import "slices" // DirectedGraph type DirectedGraph[T comparable] struct { adjList map[T][]T } // NewDirectedGraph() -> Creates a Directed Graph func NewDirectedGraph[T comparable]() *DirectedGraph[T] { gp := &DirectedGraph[T]{ adjList: make(map[T][]T), } return gp } // AddIsolatedVertex() -> Creates an isolated Vertex returns True if ok , // false if vertex already exist func (gp *DirectedGraph[T]) AddIsolatedVertex(newVertex T) bool { _, ok := gp.adjList[newVertex] if !ok { gp.adjList[newVertex] = make([]T, 0) return true } return false } // AddVertex() -> Creates a directed edge newVertex -> toVertex. Creates both // vertices if they dont exist. func (gp *DirectedGraph[T]) AddVertex(newVertex T, toVertex T) { // self loops are not allowed in this graph if newVertex == toVertex { return } gp.AddIsolatedVertex(newVertex) gp.AddIsolatedVertex(toVertex) // directed: only store the edge on the source's out-list, once. if !slices.Contains(gp.adjList[newVertex], toVertex) { gp.adjList[newVertex] = append(gp.adjList[newVertex], toVertex) } } // Order() -> returns the amount of Vertices func (gp *DirectedGraph[T]) Order() int { return len(gp.adjList) } // Size() -> returns the amount of Edges func (gp *DirectedGraph[T]) Size() int { var size int // directed: each edge is stored once, so no halving. for _, val := range gp.adjList { size += len(val) } return size } // Display() -> returns adjList[map]T []T func (gp *DirectedGraph[T]) Display() map[T][]T { return gp.adjList }