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  }