Skip to content

Commit 365a8da

Browse files
committed
add topological
1 parent 75685fa commit 365a8da

File tree

6 files changed

+208
-13
lines changed

6 files changed

+208
-13
lines changed

README.md

+16-12
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,22 @@ To test each algorithm(data structure), instead of running the file directly, yo
5050
* [LinearProbingHashST](linear_probing_hash_st.go)
5151

5252
* 4 GRAPHS
53-
54-
* [Graph](graph.go)
55-
* [DepthFirstSearch](depth_first_search.go)
56-
* [DepthFirstPaths](depth_first_paths.go)
57-
* [BreadthFirstPaths](breadth_first_paths.go)
58-
* [CC](cc.go)
59-
* [Cycle](cycle.go)
60-
* [SymbolGraph](symbol_graph.go)
61-
* [DegreesOfSeparation](cmd/degrees-of-separation/main.go)
62-
* [Digraph](digraph.go)
63-
* [DirectedDFS](directed_dfs.go)
64-
* [DirectedCycle](directed_cycle.go)
53+
* Graph
54+
* [Graph](graph.go)
55+
* [DepthFirstSearch](depth_first_search.go)
56+
* [DepthFirstPaths](depth_first_paths.go)
57+
* [BreadthFirstPaths](breadth_first_paths.go)
58+
* [CC](cc.go)
59+
* [Cycle](cycle.go)
60+
* [SymbolGraph](symbol_graph.go)
61+
* [DegreesOfSeparation](cmd/degrees-of-separation/main.go)
62+
* Digraph
63+
* [Digraph](digraph.go)
64+
* [SymbolDigraph](symbol_digraph.go)
65+
* [DirectedDFS](directed_dfs.go)
66+
* [DirectedCycle](directed_cycle.go)
67+
* [DepthFirstOrder](depth_first_order.go)
68+
* [Topological](topological.go)
6569

6670
* 5 STRING
6771

cmd/topological/main.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/******************************************************************************
2+
* Execution: go run cmd/topological/main.go filename.txt delimiter
3+
* Dependencies: Digraph.java DepthFirstOrder.java DirectedCycle.java
4+
* EdgeWeightedDigraph.java EdgeWeightedDirectedCycle.java
5+
* SymbolDigraph.java
6+
* Data files: https://algs4.cs.princeton.edu/42digraph/jobs.txt
7+
*
8+
* Compute topological ordering of a DAG or edge-weighted DAG.
9+
* Runs in O(E + V) time.
10+
*
11+
* % go run cmd/topological/main.go jobs.txt "/"
12+
* Calculus
13+
* Linear Algebra
14+
* Introduction to CS
15+
* Advanced Programming
16+
* Algorithms
17+
* Theoretical CS
18+
* Artificial Intelligence
19+
* Robotics
20+
* Machine Learning
21+
* Neural Networks
22+
* Databases
23+
* Scientific Computing
24+
* Computational Biology
25+
*
26+
******************************************************************************/
27+
28+
package main
29+
30+
import (
31+
"fmt"
32+
"os"
33+
34+
"github.com/shellfly/algo"
35+
)
36+
37+
func main() {
38+
filename, sp := os.Args[1], os.Args[2]
39+
sg := algo.NewSymbolDigraph(filename, sp)
40+
top := algo.NewTopological(sg.G())
41+
for _, v := range top.Order() {
42+
fmt.Println(sg.Name(v))
43+
}
44+
}

depth_first_order.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package algo
2+
3+
// DepthFirstOrder ...
4+
type DepthFirstOrder struct {
5+
marked []bool
6+
pre, post *Queue
7+
reversePost *Stack
8+
}
9+
10+
// NewDepthFirstOrder ...
11+
func NewDepthFirstOrder(g *Digraph) *DepthFirstOrder {
12+
d := &DepthFirstOrder{
13+
marked: make([]bool, g.V()),
14+
pre: NewQueue(),
15+
post: NewQueue(),
16+
reversePost: NewStack(),
17+
}
18+
for v := 0; v < g.V(); v++ {
19+
if !d.marked[v] {
20+
d.Dfs(g, v)
21+
}
22+
}
23+
return d
24+
}
25+
26+
// Dfs ...
27+
func (d *DepthFirstOrder) Dfs(g *Digraph, v int) {
28+
d.pre.Enqueue(v)
29+
d.marked[v] = true
30+
for _, w := range g.Adj(v) {
31+
if !d.marked[w] {
32+
d.Dfs(g, w)
33+
}
34+
}
35+
d.post.Enqueue(v)
36+
d.reversePost.Push(v)
37+
}
38+
39+
// Pre ...
40+
func (d *DepthFirstOrder) Pre() *Queue {
41+
return d.pre
42+
}
43+
44+
// Post ...
45+
func (d *DepthFirstOrder) Post() *Queue {
46+
return d.post
47+
}
48+
49+
// ReversePost ...
50+
func (d *DepthFirstOrder) ReversePost() *Stack {
51+
return d.reversePost
52+
}

symbol_digraph.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package algo
2+
3+
import (
4+
"strings"
5+
6+
"github.com/shellfly/algo/stdin"
7+
)
8+
9+
// SymbolDigraph ...
10+
type SymbolDigraph struct {
11+
st ST
12+
keys []string
13+
g *Digraph
14+
}
15+
16+
// NewSymbolDigraph ...
17+
func NewSymbolDigraph(filename, sp string) *SymbolDigraph {
18+
st := NewST()
19+
in := stdin.NewInByLine(filename)
20+
for !in.IsEmpty() {
21+
a := strings.Split(in.ReadString(), sp)
22+
for i := 0; i < len(a); i++ {
23+
if !st.Contains(a[i]) {
24+
st.Put(a[i], st.Size())
25+
}
26+
}
27+
}
28+
29+
keys := make([]string, st.Size())
30+
for _, name := range st.Keys() {
31+
keys[st.Get(name)] = name
32+
}
33+
34+
g := NewDigraphV(st.Size())
35+
in = stdin.NewInByLine(filename)
36+
for !in.IsEmpty() {
37+
a := strings.Split(in.ReadString(), sp)
38+
v := st.Get(a[0])
39+
for i := 1; i < len(a); i++ {
40+
g.AddEdge(v, st.Get(a[i]))
41+
}
42+
}
43+
return &SymbolDigraph{st, keys, g}
44+
}
45+
46+
// Contains ...
47+
func (s *SymbolDigraph) Contains(key string) bool {
48+
return s.st.Contains(key)
49+
}
50+
51+
// Index ...
52+
func (s *SymbolDigraph) Index(key string) int {
53+
return s.st.Get(key)
54+
}
55+
56+
// Name ...
57+
func (s *SymbolDigraph) Name(v int) string {
58+
return s.keys[v]
59+
}
60+
61+
// G ...
62+
func (s *SymbolDigraph) G() *Digraph {
63+
return s.g
64+
}

symbol_graph.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func NewSymbolGraph(filename, sp string) *SymbolGraph {
3434
g := NewGraphV(st.Size())
3535
in = stdin.NewInByLine(filename)
3636
for !in.IsEmpty() {
37-
a := strings.Split(in.ReadString(), " ")
37+
a := strings.Split(in.ReadString(), sp)
3838
v := st.Get(a[0])
3939
for i := 1; i < len(a); i++ {
4040
g.AddEdge(v, st.Get(a[i]))

topological.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package algo
2+
3+
// Topological ...
4+
type Topological struct {
5+
order []int
6+
}
7+
8+
// NewTopological ...
9+
func NewTopological(g *Digraph) *Topological {
10+
t := new(Topological)
11+
cycleFinder := NewDirectedCycle(g)
12+
if !cycleFinder.HasCycle() {
13+
dfs := NewDepthFirstOrder(g)
14+
order := []int{}
15+
for _, v := range dfs.ReversePost().Slice() {
16+
order = append(order, v.(int))
17+
}
18+
t.order = order
19+
}
20+
return t
21+
}
22+
23+
// Order ...
24+
func (t *Topological) Order() []int {
25+
return t.order
26+
}
27+
28+
// IsDAG ...
29+
func (t *Topological) IsDAG() bool {
30+
return t.order != nil
31+
}

0 commit comments

Comments
 (0)