Trees
BST add complexity
O(height)
BST and binary tree operations are ALL
O(height) meaning that worst case is O(n) cuz that's worst height best case is O(Log n) cuz that's ideal height
binary tree with n nodes is balanced if its height is
O(log n)...binary tree with max nodes for its height has height O(log n), but O(n) height if minimum number of nodes
height of balanced binary tree
O(log n)...in worst case for an unbalanced/skewed binary tree it is O(n)
worst space complexity of binary search tree
O(n) (degenerates to list!)
BST search complexity
O(n) time is worst case for BST because it's when data is inserted in sorted order O(Height), in summary
using Java trees for expressions
expressions are evaluated with inorder traversals...you have a binary operator tree whose left subtree is a value (and maybe other operators), as is the right subtree can add unary operators, conditionals, etc. if you want to evaluate the expression, just take left subtree "binary/unsary operator" right subtree...USUALLY ROOTS = OPERATORS, leaves are numbers
binary tree is weight balanced if
for each node the numbers of inner nodes in its left subtree and right subtree differ by at most 1. **a weight balanced tree is height balanced but not always vice versa
minimum number of nodes in a binary tree of height h
h + 1 (i.e. one node per level)
internal/inner node of a tree
has a child
balanced binary tree
height of left and right subtree differ by at most 1
height of tree
height of the root (length of longest path from root to a leaf)
In order traversal
process the left subtree (in inorder); process the root; process the right subtree (in inorder)
postorder
process the left subtree (in postorder); process the right subtree (in postorder). process the root;
preorder
process the root; process the left subtree (in preorder); process the right subtree (in preorder).
insert A4
public VirusTree insert(Person c, Person p) VirusTree sub= getNode(c); VirusTree par= getNode(p); if (c == null || p == null || sub != null || par == null) throw new IllegalArgumentException(); VirusTree ch= new VirusTree(c); par.children.add(ch); return ch; }
contains A4
public boolean contains(Person p) { if (root == p) return true; for (VirusTree ch : children) { if (ch.contains(p)) return true; } return false;
size A4
public int size() { // TODO 2. This method must be recursive. if (children.size() == 0) return 1; int num= 0; for (VirusTree ch : children) { num= num + ch.size(); } return num + 1; }
BST insert
put value into tree To insert: search for value, if not found put in tree where search ends worst case: tree degenerates to list, O(n) insertion best case: O(log n), when height is O(Log n)
downward path
sequence of nodes/edges leading to node of interest (given as list of nodes: (A, B, C))
forest
set of 0 or more disjoint trees (disjoint as in no two trees have a node in common)
level of node
1 + depth
max number of nodes at depth d (of a binary tree)
2^d
searching for a node satisfying some property
(1) Base case: process an empty tree. (2) Base case: check the root, (3) Check each child in turn, returning a suitable node if the property is found, and (4) Take care of the case that no node has the property. Example: /** Return a node of tree t with value v. * If no node contains v, return null. * Note: t = null denotes the empty tree. */ public static Node getNode(Node t, int v) { if (t == null) return null; if (t.val == v) return t; for (Node ch : t.children) { Node n= getNode(ch, v); if (n != null) return n; } return null; }
empty tree has height
-1
interface ExpTree
/** An instance is an expression tree. */ public interface ExpTree { /** Return the value of this tree. */ int eval(); /** Return the preorder of this tree. */ String preorder(); /** Return the postorder of this tree. */ String postorder(); /** Return the inorder of this tree, with binary ops parenthesized. */ String inorder(); }
binary operator class
/** Constructor: left operand left, operator op, * and right operand right. */ public BinaryOp(ExpTree left, String op, ExpTree right) { leftExp= left; this.op= op; riteExp= right; } /** Return the inorder version of this expression, parenthesized. */ public @Override String inorder() { return "(" + leftExp.inorder() + " " + op + " " + riteExp.inorder() + ")"; jj
insertion in BST method
/** Insert v into BST t if it is not there. * Return true if it was inserted, false otherwise * Precondition: t is not null. */ public static boolean insert(Node t, int v) { // inv: t != null; if v is in the original tree, v in t while (true) { if (t.val == v) return false; if (v < t.val) { if (t.left != null) t= t.left; else { t.left= new Node(v); return true; } } else { // v > t.val if (t.right != null) t= t.right; else { t.right= new Node(v); return true; } } } }
finding maximum of something using recursion (example is oldestGen())
/** Return the maximum number of generations that this PhD can trace * back in their committee history * public int oldestGen() { int oldest= 0; for (PhD cm : committee) { oldest= Math.max(oldest, 1 + cm.oldestGen()); } return oldest; }
model for counting number of nodes with a property
/** Return the number of leaves of tree t. * Precondition: t is not null. */ public static int leaves(Node t) { if (t.children.size() = 0) return 1; int sum= 0; for (Node ch : t.children) { sum= sum + leaves(ch); } return sum; }
BST contains method
/** Return true if v is in tree t and false otherwise. * Takes O(d) time, where d is the maximum depth of t * Precondition t is a BST --t being null means an empty tree */ public static boolean contains(Node t, int v) { if (t == null) return false; if (v == t.data) return true; if (v < t.data) return contains(t.left, v); return contains(t.right, v);
isBST method
/** Return true iff t is a binary search tree in which all values are in the * range h..k. * Note: t = null denotes the empty tree. */ public static boolean isBST(TNode t, int h, int k) { if (t == null) return true; if (t.val < h || k < t.val) return false; return isBST(t.left, h, t.val-1) && isBST(t.right, t.val+1, k); }
binary search tree (BST) invariant
1. each node has value 2. for each node, all values in left subtree are less than the node's value 3. for each node, all values in right subtree are greater than node's value **so a BST cannot have duplicate values
deletion from BST process
1. no children (just delete) 2. 1 child (replace with that child) 3. 2 children (find successor node, i.e. minimum value of right subtree and replace) if right subtree doesn't have a left branch, still copy successor but short circuit (i.e. pointer surpasses successor node)
maximum number of nodes in a binary tree of height h
2^(h+1) - 1 (perfect tree)
subtree
A tree that is part of another tree.
Tree traversals
Always start with ACTUAL root, then recurse...look at left subtree or right etc
if you're given the inorder, can you recover the tree uniquely? no
BCAED can draw many trees
BST contains method complexity vs binary tree contains
BST: O(height) *one recursive call, height is either O(n) or O(log n) Binary tree: 2 recursive calls (O(n)) worst case Binary search on arrays: O(log n)
searching in a balanced BST requires
Best case: O(log n) time, think like binary search! either left or right subtree...this is when BST has height O(log n) Worst case: O(n) height (skewed, UNBALANCED tree) = O(n) search time
binary tree is height balanced if
FOR EACH node the heights of its subtrees differ by at most 1. (Remember, the height of an empty subtree is -1) (THIS IS DEFAULT...if it asks about balanced, think height balanced)
two trees are equal if
If this and ob are not of the same class, they are not equal, so return false.<br> * 2. Two VirusTrees are equal if<br> * -- (1) they have the same root Person object (==) AND<br> * -- (2) their children sets are the same size AND<br> * -- (3) their children sets are equal.<br> * ------ Since their sizes are equal, this requires:<br> * -------- for every VirusTree dt1 in one set there is a VirusTree<br> * -------- dt2 in the other set for which dt1.equals(dt2) is true.
public Person commonAncestor(Person child1, Person child2)
List<Person> l1= virusRouteTo(child1); List<Person> l2= virusRouteTo(child2); // If child1 or child2 is null, then the corresponding list will be null // If child1 or child2 is not in the list, the corresponding list will // be null if (l1 == null || l2 == null) return null; Person[] a1= l1.toArray(new Person[0]); Person[] a2= l2.toArray(new Person[0]); for (int i= Math.min(a1.length - 1, a2.length - 1); i >= 0; i-- ) { boolean same= true; for (int j= i; j >= 0; j-- ) { if (a1[j] != a2[j]) same= false; } if (same) return a1[i]; } return null;
can trees have reflexive edges?
NO
creating balanced BST from sorted array
[h ...sorted.... k] make middle value the root put h...m-1 to left subtree put m+1...k in right subtree (recursively)
binary tree
a tree in which each node has at most two children (called left child, right child)
tree applications
arithmetic expressions, hard drive organization, family tree...
edge
branches of trees (assumed to point down)
insertion in binary search tree pseudocode
check, whether value in current node and a new value are equal. If so, duplicate is found. Otherwise, if a new value is less, than the node's value:if a current node has no left child, place for insertion has been found;otherwise, handle the left child with the same algorithm. if a new value is greater, than the node's value:if a current node has no right child, place for insertion has been found;otherwise, handle the right child with the same algorithm.
tree
data structure with nodes each node may have zero or more successors/children each node has exactly one predecessor/parent (except root) all nodes are reachable from root
descendent/ancestor/sibling for tree
descendent/ancestor is not necessarily directly connected sibling is "on same level"
nodes
element of tree
general tree
every node can have arbitrary # of children
public List<Person> virusRouteTo(Person c) {
if (c == root) { List<Person> rou= new LinkedList<>(); rou.add(c); return rou; } for (VirusTree ch : children) { List<Person> rou2= ch.virusRouteTo(c); if (rou2 != null) { rou2.add(0, root); return rou2; } } return null;
public int widthAtDepth(int d) throws IllegalArgumentException {
if (d == 0) return 1; if (d < 0) throw new IllegalArgumentException(); int width= 0; for (VirusTree ch : children) { width= width + ch.widthAtDepth(d - 1); } return width;
public boolean equals(Object ob)
if (ob == null || ob.getClass() != getClass()) return false; VirusTree o= (VirusTree) ob; if (o.root != root) return false; if (children.size() != o.children.size()) return false; for (VirusTree ch : o.children) { if (!help(ch, children)) return false; } return true; } /** Return true iff st equals some member of s2 */ private boolean help(VirusTree st, Set<VirusTree> s2) { if (s2 == null || st == null) return false; for (VirusTree ch : s2) { if (st.equals(ch)) return true; } return false; }
public int depth(Person p)
if (root == p) return 0; for (VirusTree ch : children) { int d= ch.depth(p); if (d != -1) return 1 + d; } return -1; }
how to write recursive methods for binary trees
if tree is null (base case, tree is empty) if tree root is something (do something) repeat this method with left and right subtree (recursive portion!)...FOR BOOLEAN RETURNS, follow the if not this return false, if not this return false, then at end return true pattern
how to list BST values in ascending order
inorder traversal
size of tree
number of nodes in it
class Heap with inner class
it is a min heap with priority /** A heap of elements of type E. */ public class Heap { private class Item { private E val; private double priority; public Item(E v, double p) { val= v; priority= p; } public String toString() { return "(" + val + ", " + priority + ")"; } }
Perfect binary tree with 2^(k) -1 nodes has
k levels Add one more node: 2^k nodes has k+1 levels Add one more node: n = 2^k nodes has O(log n) levels
height of node
length of longest path from node to leaf
depth of node
length of path from root to node
perfect tree
max # of nodes
width of tree
max width across all depths
If a binary tree has n nodes, what is the maximum and minimum depth it could be?
min depth: floor(log2(n)) max: n- 1
complete tree
no holes at each level (except last), bottom nodes are as far left as possible
only the root node can have
no parents (NO OTHER!)
leaves
nodes with no successors(no children)
can you construct a tree from preorder and postorder?
nope, need inorder and something else!
inner nodes
not root, not leaves
a binary tree is either
null or an object with a left or right subtree (recursion!)
degree of node
number of children (leaf has degree zero, i.e. no children)
width of tree at depth d
number of nodes at depth d
root
the first element of a tree(the topmost)**no parents
length of path
the number of edges in a path i.e. (B) is length zero because path from B to B
a list is a special form of a
tree
if you're given inorder or preorder, can you determine tree uniquely?
yes!!!!! **can also do with postorder, where postorder tells you root! what is root? preorder tells you what comes before/after root A? Inorder tells us ...if BEFORE, then left, if AFTER, then right Now recurse! (preorder still tells you root!!!) you will ADD nodes in the preorder order whereas inorder tells you in general whether to add to left or right subtree
are trees data structures?
yes, data structure with nodes, similar to a linked list