1.Type of Tree
1. Binary Tree:
a binary tree is a tree in which each node has at most two child nodes(denoted as the left child and the right child).
- A directed edge refers to the link from the parent to the child (the arrows in the picture of the tree).
- The root node of a tree is the node with no parents. There is at most one root node in a rooted tree.
- A leaf node has no children.
- The depth (or height) of a tree is the length of the path from the root to the deepest node in the tree. A (rooted) tree with only one node (the root) has a depth of zero.
- Siblings are those nodes that share the same parent node.
- A node p is an ancestor of a node q if p exists on the path from the root node to node q. The node q is then termed as a descendant of p.
- The size of a node is the number of descendants it has including itself.
- The in-degree of a node is the number of edges arriving at that node.
- The out-degree of a node is the number of edges leaving that node.
- The root is the only node in a tree with an in-degree of 0.
- All the leaf nodes have an out-degree of 0.
2. perfect binary tree:
A perfect binary tree is a full binary tree in which all leaves are at the same depth or same level, and in which every parent has two children.[2] (This is ambiguously also called a complete binary tree (see next).) An example of a perfect binary tree is the ancestry chart of a person to a given depth, as each person has exactly two biological parents (one mother and one father); note that this reverses the usual parent/child tree convention, and these trees go in the opposite direction from usual (root at bottom).
3. complete binary tree:
A complete binary tree is a binary tree in which every level, except possibly the last, is completely filled, and all nodes are as far left as possible.[3] A tree is called an almost complete binary tree or nearly complete binary tree if the exception holds, i.e. the last level is not completely filled. This type of tree is used as a specialized data structure called a heap.
4.Balanced Binary Tree:
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
the tree is only balanced if:
- The left and right subtrees' heights differ by at most one, AND
- The left subtree is balanced, AND
- The right subtree is balanced
so tree like this is also balanced:
o
/ \
o o
/ / \
o o o
/
o
5. Binary Search Tree:
a binary search tree (BST), sometimes also called an ordered orsorted binary tree, is a node-based binary tree data structure which has the following properties:[1]
- The left subtree of a node contains only nodes with keys less than the node's key.
- The right subtree of a node contains only nodes with keys greater than the node's key.
- The left and right subtree each must also be a binary search tree.
- There must be no duplicate nodes.
Binary search tree | ||
---|---|---|
Type | Tree | |
Time complexity in big O notation | ||
Average | Worst case | |
Space | O(n) | O(n) |
Search | O(log n) | O(n) |
Insert | O(log n) | O(n) |
Delete | O(log n) | O(n) |
2. Binary Tree Traversal
in-order, pre-order, post-order
这三种都可以使用recursive 来实现,也可以使用iterative。 见
in-order http://www.cnblogs.com/reynold-lei/p/3458710.html
pre-order http://www.cnblogs.com/reynold-lei/p/3443067.html
post-order http://www.cnblogs.com/reynold-lei/p/3455756.html
3. Tries
trie,又称前缀树或字典樹,是一种有序树,用于保存关联数组,其中的键通常是字符串。与二叉查找树不同,键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子孙都有相同的前缀,也就是这个节点对应的字符串,而根节点对应空字符串。一般情况下,不是所有的节点都有对应的值,只有叶子节点和部分内部节点所对应的键才有相关的值。
一个保存了 8 个键的 trie 结构,"A", "to", "tea", "ted", "ten", "i", "in", and "inn".
In the example shown, keys are listed in the nodes and values below them. Each complete English word has an arbitrary integer value associated with it. A trie can be seen as adeterministic finite automaton, although the symbol on each edge is often implicit in the order of the branches.
It is not necessary for keys to be explicitly stored in nodes. (In the figure, words are shown only to illustrate how the trie works.)
Though tries are most commonly keyed by character strings, they don't need to be. The same algorithms can easily be adapted to serve similar functions of ordered lists of any construct, e.g., permutations on a list of digits or shapes. In particular, a bitwise trie is keyed on the individual bits making up a short, fixed size of bits such as an integer number or memory address.
4. Tree Balancing: Red-Black Trees and AVL Trees
Problem:
4.1 check if a binary tree is balanced.
public int getHeight(TreeNode root){
if(root == null) return 0;
return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
} public boolean isBalanced(TreeNode root){
if(root == null) return true;
if(Math.abs(getHeight(root.left) - getHeight(root.right)) > 1){
return false;
}else{
return isBalanced(root.left) && isBalanced(root.right);
}
}
这段代码写的很简洁, 值得学习!
4.3 give a sorted array(increasing order), create a binary search tree with minimal height.
Solution:(recurse) 1 insert into the tree the middle element of the array
2 insert into the left subarray elements
3 insert into the right subarray elements
TreeNode create(int arr[], int start, int end){
if(end < start) return null;
int mid = (start + end) / 2;
TreeNode n = new TreeNode(arr[mid]);
n.left = create(arr, start, mid - 1);
n.right = create(arr, mid + 1, end);
return n;
} TreeNode createBST(int arr[]){
return create(arr, 0 , arr.length - 1);
}
4.4 Given a binary search tree, design an algo which creates a linked list of all nodes at each depth. (same as leetcode)
void createLevelLinkedList(TreeNode root, ArrayList<LinkedList<TreeNode>> lists, int level){
if(root == null) return;
LinkedList<TreeNode> list = null;
if(lists.size() == level) lists.add(list);
else list = lists.get(level);
list.add(root);
createLevelLinkedList(root.left, lists, level + 1);
createLevelLinkedList(root.right, lists, level + 1);
}
ArrayList<LinkedList<TreeNode>> createLevelLinkedList(TreeNode root){
ArrayList<LinkedList<TreeNode>> lists = new ArrayList<LinkedList<TreeNode>>();
createLevelLinkedList(root, lists, 0);
return lists;
}
4.5 Implement a function to check if a binary tree is a binary search tree.
Function 1: In-order traversal : copy elements into an array, check if the array is sorted.
Notice that we only need to track the last element.
int last_printed = Integer.MIN_VALUE;
public boolean checkBST(TreeNode n){
if(n == null) return true;
if(!checkBST(n.left)) return false;
if(n.data < last_printed) return false;
last_printed = n.data;
if(!checkBST(n.right)) return false;
return true;
}
Function 2: The Min / Max Solution : the condition is that all left nodes must be less than or equals to the current node, which must be less than all right nodes.
boolean checkBST(TreeNode n){
return checkBST(n, Integer.MIN_VALUE, Integer.MAX_VALUE);
} boolean checkBST(TreeNode n, int min, int max){
if(n == null) return true;
if(n.data <= min || n.data > max) return false;
if(!checkBST(n.left, min, n.data) || !checkBST(n.right, n.data, max)) return false;
return true;
}
4.6 find the 'next' node, i.e, in-order successor, of a given node in a binary search tree. (each node has a link to its parent)
public TreeNode inorderSucc(TreeNode n){
if(n == null) return null; //find right children -> return leftmost node of right subtree, n.parent == null is the root node
if(n.parent == null || n.right != null) return leftmost(n.right);
else{
TreeNode q = n;
TreeNode x = q.parent;
//go up until we are on left instead of right
while(x != null && x.left != q){
q = x;
x = x.parent;
}
return x;// if n is the right most node, it will return null
}
} public TreeNode leftmost(TreeNode n){
if(n == null) return null;
while(n.left != null) n = n.left;
return n;
}
4.7 Find the first common ancestor of two nodes in a binary tree. Note: this is not necessarily a binary search tree.
if the tree is BST:
TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q){
if(root == null || p == null || q == null) return false;
if(root.val > p.val && root.val > q.val) return commonAncestor(root.left, p, q);
else if(root.val < p.val && root.val < q.val) return commonAncestor(root.right, p, q);
else return root;
}
in the same way, we can check which p and q are on the same side.
//returns true if p is a descendent of root
boolean covers(TreeNode root, TreeNode p){
if(root == null) return false;
if(root == p) return true;
return covers(root.left, p) || covers(root.right, p);
}
TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q){
if(root == null) return null;
if(root == p || root == q) return root;
boolean is_p_on_left = covers(root.left, p);
boolean is_q_on_right = covers(root.right, q);
//if p and q are on different sides, return root
if(is_q_on_right != is_p_on_left) return root; //else, they are on the same side, traverse this side.
TreeNode child = is_p_on_left ? root.left : root.right;
return commonAncestor(child, p, q);
}
TreeNode main(TreeNode root, TreeNode p, TreeNode q){
if(!covers(root, p) || !covers(root, q)) return null;
return commonAncestor(root, p, q);
}
4.9 Given a binary tree in which each node contains a value. Design an algo to print all paths which sum to a given value. Note that path can start or end anywhere in the tree.
这一题不是太懂!