skip to content
tamagoyaki logo

tamagoyaki

topological sort and strongly connected components

topological sort

start *Vector path [] *Vector

  • run on a directed acyclic graph
  • run dfs
    • we need a starting point
    • we find the “sinks” vectors and add them to the path, this is the same of processing a vector
  • return reversed path
func (GD *GraphDirected) TopologicalSort(G *GraphAL) []*GraphVector {
	if G.size < 1 || G.HasCycle() {
		return nil
	}
	path := []*GraphVector{}
	visited := make([]bool, G.size)
	for _, vector := range G.vectors {
		G.dfsWithCallback(vector, &visited, func(gv *GraphVector) {}, func(gv *GraphVector) {
			path = append([]*GraphVector{gv}, path...)
		})
	}
	return path
}

topologicalsort

topologicalsortcycle

StronglyConnectedComponentsList

componentslist [][]*Vector

  • reverse the graph
  • get the counter and store in a queue being the first element the one with the biggest count
  • reverse
  • run dfs in the queue order with the original graph
    • append to the componentlist[counter] += vector, the current visited vector or the current component
  • every time you finish with dfs increase the counter, this is to add a new component to the componentlist

func (G *GraphAL) StronglyConnectedComponentsList() [][]*GraphVector {
	G.Reverse()
	postorderVectors := G.TimesDfsVectors()
	G.Reverse()
	counter := 0
	componentlist := [][]*GraphVector{}
	visited := make([]bool, G.size)
	for i := G.size - 1; i >= 0; i-- {
		vector := postorderVectors[i]
		if !visited[vector.index] {
			componentlist = append(componentlist, []*GraphVector{})
			G.dfsWithCallback(vector, &visited, func(gv *GraphVector) {}, func(gv *GraphVector) {
				componentlist[counter] = append(componentlist[counter], gv)
			})
			counter++
		}
	}
	return componentlist
}

checkForReverseCycle()

we want to check before we reverse the edges if the vector is already present in the list of edges of the other vector, if true then we have a cycle between the vectors

func (G *GraphAL) interconnected(a, b *GraphVector) bool {
	current := b.edges.FrontNode()
	for current != nil && current.Val() != nil {
		if current.Val().(*GraphVector) == a {
			return true
		}
		current = current.Next()
	}

	return false
}