Skip to content

Commit 5a331a7

Browse files
committed
BSTIterator
1 parent 7ef73d9 commit 5a331a7

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package binary_search_tree_iterator
2+
3+
import (
4+
"testing"
5+
6+
"github.com/masx200/leetcode-test/utils"
7+
"gotest.tools/v3/assert"
8+
)
9+
10+
var TreeNodeLeetCodeParse = utils.TreeNodeLeetCodeParse
11+
12+
func TestBSTIterator(t *testing.T) {
13+
iterator := Constructor(TreeNodeLeetCodeParse("[7, 3, 15, null, null, 9, 20]"))
14+
res := []int{}
15+
for iterator.HasNext() {
16+
res = append(res, iterator.Next())
17+
}
18+
assert.DeepEqual(t, res, []int{3, 7, 9, 15, 20})
19+
}

binary-search-tree-iterator/index.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package binary_search_tree_iterator
2+
3+
import (
4+
"context"
5+
serialize_and_deserialize_binary_tree "github.com/masx200/leetcode-test/serialize-and-deserialize-binary-tree"
6+
"runtime"
7+
)
8+
9+
type TreeNode = serialize_and_deserialize_binary_tree.TreeNode
10+
11+
type BSTIterator struct {
12+
generator chan int
13+
value int
14+
done bool
15+
}
16+
17+
func Constructor(root *TreeNode) BSTIterator {
18+
ctx, cancel := context.WithCancel(context.Background())
19+
gen := InOrderIterator(ctx, root)
20+
21+
value, done := <-gen
22+
bstiterator := BSTIterator{generator: gen, value: value, done: done}
23+
runtime.SetFinalizer(&bstiterator, func(_ *BSTIterator) { cancel() })
24+
return bstiterator
25+
}
26+
27+
func (b *BSTIterator) Next() int {
28+
val := b.value
29+
b.value, b.done = <-b.generator
30+
return val
31+
}
32+
33+
func (b *BSTIterator) HasNext() bool {
34+
return b.done
35+
}
36+
37+
func InOrderIterator(ctx context.Context, root *TreeNode) (gen chan int) {
38+
gen = make(chan int)
39+
40+
go func() {
41+
42+
defer close(gen)
43+
if root == nil {
44+
45+
return
46+
}
47+
YieldAll(ctx, gen, InOrderIterator(ctx, root.Left))
48+
YieldOne(
49+
ctx, gen, root.Val)
50+
51+
YieldAll(ctx, gen, InOrderIterator(ctx, root.Right))
52+
53+
}()
54+
55+
return
56+
}
57+
func YieldAll(ctx context.Context, target chan int, source chan int) {
58+
59+
for v := range source {
60+
YieldOne(
61+
ctx, target, v)
62+
63+
}
64+
}
65+
func YieldOne(ctx context.Context, target chan int, source int) {
66+
67+
select {
68+
case <-ctx.Done():
69+
return
70+
default:
71+
target <- source
72+
}
73+
74+
}

0 commit comments

Comments
 (0)