@@ -4,15 +4,19 @@ package graph
44// If no such walk exists, it returns an empty walk and sets ok to false.
55func EulerDirected (g Iterator ) (walk []int , ok bool ) {
66 n := g .Order ()
7- // Compute outdegree - indegree for each vertex.
8- degree := make ([] int , n )
7+ degree := make ([] int , n ) // outdegree - indegree for each vertex
8+ edgeCount := 0
99 for v := range degree {
1010 g .Visit (v , func (w int , _ int64 ) (skip bool ) {
11+ edgeCount ++
1112 degree [v ]++
1213 degree [w ]--
1314 return
1415 })
1516 }
17+ if edgeCount == 0 {
18+ return []int {}, true
19+ }
1620
1721 start , end := - 1 , - 1
1822 for v := range degree {
@@ -28,42 +32,38 @@ func EulerDirected(g Iterator) (walk []int, ok bool) {
2832 }
2933
3034 // Make a copy of g
31- edgeCount := 0
3235 h := make ([][]int , n )
3336 for v := range h {
3437 g .Visit (v , func (w int , _ int64 ) (skip bool ) {
3538 h [v ] = append (h [v ], w )
36- edgeCount ++
3739 return
3840 })
3941 }
40- if edgeCount == 0 {
41- return []int {}, true
42- }
4342
4443 // Find a starting point with neighbors.
45- for v := 0 ; v < n && start == - 1 ; v ++ {
46- if len (h [v ]) > 0 {
47- start = v
44+ if start == - 1 {
45+ for v , neighbors := range h {
46+ if len (neighbors ) > 0 {
47+ start = v
48+ break
49+ }
4850 }
4951 }
5052
51- stack := []int {start }
52- for len (stack ) > 0 {
53- v := stack [len ( stack ) - 1 ]
54- stack = stack [:len ( stack ) - 1 ]
53+ for stack := []int {start }; len ( stack ) > 0 ; {
54+ n := len (stack )
55+ v := stack [n - 1 ]
56+ stack = stack [:n - 1 ]
5557 for len (h [v ]) > 0 {
5658 stack = append (stack , v )
5759 v , h [v ] = h [v ][0 ], h [v ][1 :]
5860 edgeCount --
5961 }
6062 walk = append (walk , v )
6163 }
62-
63- if edgeCount != 0 {
64+ if edgeCount > 0 {
6465 return []int {}, false
6566 }
66-
6767 for i , j := 0 , len (walk )- 1 ; i < j ; i , j = i + 1 , j - 1 {
6868 walk [i ], walk [j ] = walk [j ], walk [i ]
6969 }
@@ -75,16 +75,20 @@ func EulerDirected(g Iterator) (walk []int, ok bool) {
7575// and sets ok to false.
7676func EulerUndirected (g Iterator ) (walk []int , ok bool ) {
7777 n := g .Order ()
78- // Compute outdegree for each vertex.
79- out := make ([] int , n )
78+ out := make ([] int , n ) // outdegree for each vertex
79+ edgeCount := 0
8080 for v := range out {
8181 g .Visit (v , func (w int , _ int64 ) (skip bool ) {
82+ edgeCount ++
8283 if v != w {
8384 out [v ]++
8485 }
8586 return
8687 })
8788 }
89+ if edgeCount == 0 {
90+ return []int {}, true
91+ }
8892
8993 start , oddDeg := - 1 , 0
9094 for v := range out {
@@ -97,52 +101,40 @@ func EulerUndirected(g Iterator) (walk []int, ok bool) {
97101 return []int {}, false
98102 }
99103
100- // Make a copy of g.
101- edgeCount := 0
102- h := New (n )
103- for v := 0 ; v < n ; v ++ {
104- g .Visit (v , func (w int , _ int64 ) (skip bool ) {
105- h .Add (v , w )
106- edgeCount ++
107- return
108- })
109- }
110- if edgeCount == 0 {
111- return []int {}, true
112- }
113-
114104 // Find a starting point with neighbors.
115- for v := 0 ; v < n && start == - 1 ; v ++ {
116- h .Visit (v , func (w int , _ int64 ) (skip bool ) {
117- start = w
118- return true
119- })
105+ if start == - 1 {
106+ for v := 0 ; v < n ; v ++ {
107+ if g .Visit (v , func (w int , _ int64 ) (skip bool ) {
108+ start = w
109+ return true
110+ }) {
111+ break
112+ }
113+ }
120114 }
121115
122- stack := []int {start }
123- for len (stack ) > 0 {
124- v := stack [len (stack )- 1 ]
125- stack = stack [:len (stack )- 1 ]
116+ h := Copy (g )
117+ for stack := []int {start }; len (stack ) > 0 ; {
118+ n := len (stack )
119+ v := stack [n - 1 ]
120+ stack = stack [:n - 1 ]
126121 for h .Degree (v ) > 0 {
127122 stack = append (stack , v )
128123 var w int
129124 h .Visit (v , func (u int , _ int64 ) (skip bool ) {
130125 w = u
131126 return true
132127 })
128+ h .DeleteBoth (v , w )
129+ edgeCount --
133130 if v != w {
134- h .DeleteBoth (v , w )
135- edgeCount -= 2
136- } else {
137- h .Delete (v , v )
138131 edgeCount --
139132 }
140133 v = w
141134 }
142135 walk = append (walk , v )
143136 }
144-
145- if edgeCount != 0 {
137+ if edgeCount > 0 {
146138 return []int {}, false
147139 }
148140 return walk , true
0 commit comments