The Algorithms logo
The Algorithms
AboutDonate

Bstree

package binarytree

// BSTree Returns a binary search tree structure which contains only a root Node
type BSTree struct {
	Root *Node
}

// calculateDepth helper function for BSTree's depth()
func calculateDepth(n *Node, depth int) int {
	if n == nil {
		return depth
	}
	return Max(calculateDepth(n.left, depth+1), calculateDepth(n.right, depth+1))
}

// Insert a value in the BSTree
func Insert(root *Node, val int) *Node {
	if root == nil {
		return NewNode(val)
	}
	if val < root.val {
		root.left = Insert(root.left, val)
	} else {
		root.right = Insert(root.right, val)
	}
	return root
}

// Depth returns the calculated depth of a binary saerch tree
func (t *BSTree) Depth() int {
	return calculateDepth(t.Root, 0)
}

// InOrderSuccessor Goes to the left
func InOrderSuccessor(root *Node) *Node {
	cur := root
	for cur.left != nil {
		cur = cur.left
	}
	return cur
}

// BstDelete removes the node
func BstDelete(root *Node, val int) *Node {
	if root == nil {
		return nil
	}
	if val < root.val {
		root.left = BstDelete(root.left, val)
	} else if val > root.val {
		root.right = BstDelete(root.right, val)
	} else {
		// this is the node to delete
		// node with one child
		if root.left == nil {
			return root.right
		} else if root.right == nil {
			return root.left
		} else {
			n := root.right
			d := InOrderSuccessor(n)
			d.left = root.left
			return root.right
		}
	}
	return root
}

// InOrder add's children to a node in order left first then right recursively
func inOrderRecursive(n *Node, traversal *[]int) {
	if n != nil {
		inOrderRecursive(n.left, traversal)
		*traversal = append(*traversal, n.val)
		inOrderRecursive(n.right, traversal)
	}
}

// Travers the tree in the following order left --> root --> right
func InOrder(root *Node) []int {
	traversal := make([]int, 0)
	inOrderRecursive(root, &traversal)
	return traversal
}

// PreOrder Preorder
func preOrderRecursive(n *Node, traversal *[]int) {
	if n == nil {
		return
	}
	*traversal = append(*traversal, n.val)
	preOrderRecursive(n.left, traversal)
	preOrderRecursive(n.right, traversal)
}

// Travers the tree in the following order root --> left --> right
func PreOrder(root *Node) []int {
	traversal := make([]int, 0)
	preOrderRecursive(root, &traversal)
	return traversal
}

// PostOrder PostOrder
func postOrderRecursive(n *Node, traversal *[]int) {
	if n == nil {
		return
	}
	postOrderRecursive(n.left, traversal)
	postOrderRecursive(n.right, traversal)
	*traversal = append(*traversal, n.val)
}

// Travers the tree in the following order left --> right --> root
func PostOrder(root *Node) []int {
	traversal := make([]int, 0)
	postOrderRecursive(root, &traversal)
	return traversal
}

// LevelOrder LevelOrder
func levelOrderRecursive(root *Node, traversal *[]int) {
	var q []*Node // queue
	var n *Node   // temporary node

	q = append(q, root)

	for len(q) != 0 {
		n, q = q[0], q[1:]
		*traversal = append(*traversal, n.val)
		if n.left != nil {
			q = append(q, n.left)
		}
		if n.right != nil {
			q = append(q, n.right)
		}
	}
}

func LevelOrder(root *Node) []int {
	traversal := make([]int, 0)
	levelOrderRecursive(root, &traversal)
	return traversal
}

// AccessNodesByLayer Function that access nodes layer by layer instead of printing the results as one line.
func AccessNodesByLayer(root *Node) [][]int {
	var res [][]int
	if root == nil {
		return res
	}
	var q []*Node
	var n *Node
	var idx = 0
	q = append(q, root)

	for len(q) != 0 {
		res = append(res, []int{})
		qLen := len(q)
		for i := 0; i < qLen; i++ {
			n, q = q[0], q[1:]
			res[idx] = append(res[idx], n.val)
			if n.left != nil {
				q = append(q, n.left)
			}
			if n.right != nil {
				q = append(q, n.right)
			}
		}
		idx++
	}
	return res
}

// Max Function that returns max of two numbers - possibly already declared.
func Max(a, b int) int {
	if a > b {
		return a
	}
	return b
}