Example #1
0
// PreOrder returns an iterator over the tree depth-first in
// preorder:
// Traverse the left subtree.
// Visit the root.
// Traverse the right subtree.
//
// e.g. for x := range (2 (1) (3)).PreOrder() { x } => 2, 1, 3
//
func (T *BinaryTree) PreOrder() chan Elem {
	ch := make(chan Elem, T.size)
	go func() {

		if T.Empty() {
			close(ch)
			return
		}

		nodes := stack.New()
		nodes.Push(T.root)

		for !nodes.Empty() {
			currentNode := nodes.Pop().(*node)
			ch <- currentNode.elem

			if currentNode.right != nil {
				nodes.Push(currentNode.right)
			}
			if currentNode.left != nil {
				nodes.Push(currentNode.left)
			}
		}

		close(ch)
	}()
	return ch
}
Example #2
0
// InOrder returns an iterator over the tree depth-first inorder:
// Visit the root.
// Traverse the left subtree.
// Traverse the right subtree.
//
// e.g. for x := range (2 (1) (3)).InOrder() { x } => 1, 2, 3
//
func (T *BinaryTree) InOrder() chan Elem {
	ch := make(chan Elem, T.size)
	go func() {

		nodes := stack.New()
		currentNode := T.root

		for {
			if currentNode != nil {
				nodes.Push(currentNode)
				currentNode = currentNode.left
			} else {
				if !nodes.Empty() {
					currentNode = nodes.Pop().(*node)
					ch <- currentNode.elem
					currentNode = currentNode.right
				} else {
					break
				}
			}
		}

		close(ch)
	}()
	return ch
}
Example #3
0
// PostOrder returns an iterator over the tree depth-first in
// postorder:
// Traverse the left subtree.
// Traverse the right subtree.
// Visit the root.
//
// e.g. for x := range (2 (1) (3)).PostOrder() { x } => 1, 3, 2
//
func (T *BinaryTree) PostOrder() chan Elem {
	ch := make(chan Elem, T.size)
	go func() {

		if T.Empty() {
			close(ch)
			return
		}

		nodes := stack.New()
		nodes.Push(T.root)
		var prev *node

		for !nodes.Empty() {
			current := nodes.Peek().(*node)

			if prev == nil || prev.left == current || prev.right == current {
				if current.left != nil {
					nodes.Push(current.left)
				} else if current.right != nil {
					nodes.Push(current.right)
				}
			} else if current.left == prev {
				if current.right != nil {
					nodes.Push(current.right)
				}
			} else {
				ch <- current.elem
				nodes.Pop()
			}
			prev = current
		}

		close(ch)
	}()
	return ch
}