github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/tests/files/extern/timtadh/data_structures/tree/utils.gno (about) 1 // from https://raw.githubusercontent.com/timtadh/data_structures/master/tree/util.gno 2 3 package tree 4 5 import ( 6 "github.com/gnolang/gno/_test/timtadh/data_structures/types" 7 ) 8 9 func pop(stack []types.TreeNode) ([]types.TreeNode, types.TreeNode) { 10 if len(stack) <= 0 { 11 return stack, nil 12 } else { 13 return stack[0 : len(stack)-1], stack[len(stack)-1] 14 } 15 } 16 17 func btn_expose_nil(node types.BinaryTreeNode) types.BinaryTreeNode { 18 if types.IsNil(node) { 19 return nil 20 } 21 return node 22 } 23 24 func tn_expose_nil(node types.TreeNode) types.TreeNode { 25 if types.IsNil(node) { 26 return nil 27 } 28 return node 29 } 30 31 func TraverseBinaryTreeInOrder(node types.BinaryTreeNode) types.TreeNodeIterator { 32 stack := make([]types.TreeNode, 0, 10) 33 var cur types.TreeNode = btn_expose_nil(node) 34 var tn_iterator types.TreeNodeIterator 35 tn_iterator = func() (tn types.TreeNode, next types.TreeNodeIterator) { 36 if len(stack) > 0 || cur != nil { 37 for cur != nil { 38 stack = append(stack, cur) 39 cur = cur.(types.BinaryTreeNode).Left() 40 } 41 stack, cur = pop(stack) 42 tn = cur 43 cur = cur.(types.BinaryTreeNode).Right() 44 return tn, tn_iterator 45 } else { 46 return nil, nil 47 } 48 } 49 return tn_iterator 50 } 51 52 func TraverseTreePreOrder(node types.TreeNode) types.TreeNodeIterator { 53 stack := append(make([]types.TreeNode, 0, 10), tn_expose_nil(node)) 54 var tn_iterator types.TreeNodeIterator 55 tn_iterator = func() (tn types.TreeNode, next types.TreeNodeIterator) { 56 if len(stack) <= 0 { 57 return nil, nil 58 } 59 stack, tn = pop(stack) 60 kid_count := 1 61 if tn.ChildCount() >= 0 { 62 kid_count = tn.ChildCount() 63 } 64 kids := make([]types.TreeNode, 0, kid_count) 65 for child, next := tn.Children()(); next != nil; child, next = next() { 66 kids = append(kids, child) 67 } 68 for i := len(kids) - 1; i >= 0; i-- { 69 stack = append(stack, kids[i]) 70 } 71 return tn, tn_iterator 72 } 73 return tn_iterator 74 } 75 76 func TraverseTreePostOrder(node types.TreeNode) types.TreeNodeIterator { 77 type entry struct { 78 tn types.TreeNode 79 i int 80 } 81 82 pop := func(stack []entry) ([]entry, types.TreeNode, int) { 83 if len(stack) <= 0 { 84 return stack, nil, 0 85 } else { 86 e := stack[len(stack)-1] 87 return stack[0 : len(stack)-1], e.tn, e.i 88 } 89 } 90 91 stack := append(make([]entry, 0, 10), entry{tn_expose_nil(node), 0}) 92 93 var tn_iterator types.TreeNodeIterator 94 tn_iterator = func() (tn types.TreeNode, next types.TreeNodeIterator) { 95 var i int 96 97 if len(stack) <= 0 { 98 return nil, nil 99 } 100 101 stack, tn, i = pop(stack) 102 for i < tn.ChildCount() { 103 kid := tn.GetChild(i) 104 stack = append(stack, entry{tn, i + 1}) 105 tn = kid 106 i = 0 107 } 108 return tn, tn_iterator 109 } 110 return tn_iterator 111 }