Skip to content

Instantly share code, notes, and snippets.

@grevych
Created August 14, 2019 22:59
Show Gist options
  • Save grevych/3f40f596404c67ba07c780f3d49e4b71 to your computer and use it in GitHub Desktop.
Save grevych/3f40f596404c67ba07c780f3d49e4b71 to your computer and use it in GitHub Desktop.
Simple Binary Tree. Iterative traversals. Link: https://goplay.space/#b08ePZaI0y-
package main
import (
"fmt"
)
type node struct {
Value int
Left *node
Right *node
}
func NewNode(value int) *node {
return &node{
Value: value,
Left: nil,
Right: nil,
}
}
type tree struct {
Root *node
}
func NewTree() *tree {
return &tree{}
}
type Tree interface {
insert(root *node, value int)
Insert(value int)
PreOrder() []int
PostOrder() []int
InOrder() []int
}
var _ Tree = &tree{}
func (t *tree) insert(parent *node, value int) {
if value < parent.Value {
if parent.Left == nil {
parent.Left = NewNode(value)
} else {
t.insert(parent.Left, value)
}
} else if value > parent.Value {
if parent.Right == nil {
parent.Right = NewNode(value)
} else {
t.insert(parent.Right, value)
}
}
}
func (t *tree) Insert(value int) {
if t.Root == nil {
t.Root = NewNode(value)
return
}
t.insert(t.Root, value)
}
func (t *tree) PreOrder() []int {
stack := []*node{t.Root}
result := []int{}
for length := len(stack); length > 0; length = len(stack) {
current := stack[length-1]
stack = stack[:length-1]
result = append(result, current.Value)
if current.Right != nil {
stack = append(stack, current.Right)
}
if current.Left != nil {
stack = append(stack, current.Left)
}
}
return result
}
func (t *tree) PostOrder() []int {
visited := map[int]*struct{}{}
stack := []*node{t.Root}
result := []int{}
for length := len(stack); length > 0; length = len(stack) {
current := stack[length-1]
if _, ok := visited[current.Value]; ok {
result = append(result, current.Value)
stack = stack[:length-1]
} else {
if current.Right != nil {
stack = append(stack, current.Right)
}
if current.Left != nil {
stack = append(stack, current.Left)
}
visited[current.Value] = nil
}
}
return result
}
func (t *tree) InOrder() []int {
visited := map[int]*struct{}{}
stack := []*node{t.Root}
result := []int{}
for length := len(stack); length > 0; length = len(stack) {
current := stack[length-1]
stack = stack[:length-1]
if _, ok := visited[current.Value]; ok {
result = append(result, current.Value)
} else {
if current.Right != nil {
stack = append(stack, current.Right)
}
stack = append(stack, current)
if current.Left != nil {
stack = append(stack, current.Left)
}
visited[current.Value] = nil
}
}
return result
}
func main() {
t := NewTree()
t.Insert(6)
t.Insert(4)
t.Insert(9)
t.Insert(2)
t.Insert(5)
t.Insert(7)
t.Insert(10)
t.Insert(1)
t.Insert(3)
t.Insert(8)
fmt.Println("PREORDER: ", t.PreOrder())
fmt.Println("POSTORDER: ", t.PostOrder())
fmt.Println("INORDER: ", t.InOrder())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment