Tree
The most basic trees: Binary Tree and Binary Search Tree. For more advanced trees, like B-Tree, Merkel Tree, check Advanced Data Structures
Tree Definition
Java
class BinaryTree {
private Node root;
public BinaryTree() {
root = null;
}
private static class Node {
Node left;
Node right;
int data;
Node(int newdata) {
left = null;
right = null;
data = newdata;
}
}
}
Go
type Tree struct {
Left *Tree
Value int
Right *Tree
}
Python
class TreeNode:
def __init__(self, val):
self.val = val
self.left, self.right = None, None
Insert Into Binary Search Tree
public Node insert(Node node, int data) {
if (node == null) {
node = new Node(data);
} else {
if (data <= node.data) {
node.left = insert(node.left, data);
} else {
node.right = insert(node.right, data);
}
}
return node;
}
Traversal
In-order
public void inorder(Node node) {
if (node == null)
return;
inorder(node.left);
System.out.println(node.data);
inorder(node.right);
return;
}
Pre-order
public void preorder(Node node){
if (node == null)
return;
System.out.println(node.data);
preorder(node.left);
preorder(node.right);
return;
}
Post-order
public void postorder(Node node){
if (node == null)
return;
postorder(node.left);
postorder(node.right);
System.out.println(node.data);
return;
}
Min/Max Depth
public int maxDepth() {
return maxDepth(root);
}
public int maxDepth(Node node){
if (node == null)
return 0;
return 1 + Math.max(maxDepth(node.left), maxDepth(node.right));
}
public int minDepth() {
return minDepth(root);
}
public int minDepth(Node node){
if (node == null)
return 0;
return 1 + Math.min(minDepth(node.left), minDepth(node.right));
}
Check Balance
public boolean isBalanced() {
return (maxDepth(root) - minDepth(root) <= 1);
}
or
public boolean isBalanced(TreeNode root) {
return balanced(root) != -1;
}
private int balanced(TreeNode root) {
if (root == null) {
return 0;
}
int left = balanced(root.left);
int right = balanced(root.right);
if (left == -1 || right == -1) {
return -1;
}
if (Math.abs(left - right) <= 1) {
return Math.max(left, right) + 1;
} else {
return -1;
}
}
Has Path Sum
Given a tree and a sum, returns true if there is a path from the root down to a leaf, such that adding up all the values along the path equals the given sum.
public boolean hasPathSum(int sum) {
return hasPathSum(root, sum);
}
public boolean hasPathSum(Node node, int sum) {
if (node == null) return (sum == 0);
return hasPathSum(node.left, sum - node.data) || hasPathSum(node.right, sum - node.data);
}
Size
public int size(Node node){
if (node == null)
return 0;
return 1 + size(node.left) + size(node.right);
}
Print Path
public void printPaths() {
int[] path = new int[size()];
printPaths(root, path, 0);
}
public void printPaths(Node node, int[] path, int len) {
if (node == null)
return;
path[len++] = node.data;
if (node.left == null && node.right == null) {
for (int i = 0; i < len; i++){
System.out.print(path[i] + " ");
}
System.out.println();
return;
} else {
printPaths(node.left, path, len);
printPaths(node.right, path, len);
}
}
Check Same
public boolean sameTree(Node a, Node b) {
if (a == null && b == null)
return true;
else if (a != null && b != null) {
return (a.data == b.data &&
sameTree(a.left, b.left) &&
sameTree(a.right, b.right));
} else {
return false;
}
}
Count Trees
For the key values 1...numKeys, how many structurally unique binary search trees are possible that store those keys?
Strategy: consider that each value could be the root. Recursively find the size of the left and right subtrees.
public static int countTrees(int n) {
if (n <= 1)
return 1;
int sum = 0;
for (int i = 1; i <= n; i++){
int left = countTrees(i-1);
int right = countTrees(n-i);
sum += left * right;
}
return sum;
}
IsComplete
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class IsComplete {
class Node {
Node left, right;
public Node(Node left, Node right) {
this.left = left;
this.right = right;
}
}
public static boolean isComplete(Node root) {
Queue<Node> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
Node head = queue.poll();
// Stop as soon as we see first null
if (head == null) {
break;
}
queue.offer(head.left);
queue.offer(head.right);
}
// the remaining elements in the queue should all be null
while (!queue.isEmpty()) {
Node head = queue.poll();
if (head != null) {
return false;
}
}
return true;
}
}