1. Basic concepts of trees
-
A tree can have nodes, roots, parents, children, siblings
-
Empty tree: A tree with no nodes
-
Root node: A tree has only one node, the root node
-
Trees can have left subtrees, right subtrees
-
Degree of nodes: is the number of subtrees
-
Degree of tree: the medium maximum of all nodes
-
Leaf node: node with degree 0
-
Non-leaf node: a node whose degree is not 0
- Layer tree: The root node is at the first layer, the children of the root node are at the second layer, and so on
- Depth of nodes: The total number of nodes on a unique path from the root node to the current node
- Node height: The total number of nodes along the path from the current node to the farthest leaf node
- Tree depth: the maximum depth of all nodes
- Tree height: The maximum height of all nodes
- The depth of the tree is equal to the height of the tree
- Ordered tree: A tree in which the children of any node have a sequential relationship
- Unordered tree: There is no sequential relationship between the children of any node in the tree
2. Binary tree
2.1. Characteristics of binary trees
- Each node has a maximum degree of 2 (a maximum of 2 subtrees)
- Left and right subtrees are ordered
- Even if a node has only one subtree, distinguish between the left and right subtrees
- A binary tree is an ordered tree
2.2. Properties of binary trees
- The i-th layer of a nonempty binary tree with at most 2^ (i-1) nodes (I >= 1)
- At most 2^ h-1 nodes in a binary tree of height H (h >= 1)
- For any non-empty binary tree, if the number of leaf nodes is N0 and the number of nodes with degree 2 is n2, then: n0 = n2 + 1
- Assuming that the number of nodes with degree 1 is N1, then the total number of nodes in the binary tree is n = N0 + N1 + n2
- The number of edges of the binary tree T = n1 + 2*n2 = n-1 = N0 + N1 + n2-1
- So n0 is equal to n2 plus 1
2.3. True binary trees
- All nodes have a degree of either 0 or 2
2.4. Full binary tree
- Full binary tree: The degree of the last node is 0, and the degree of the other nodes is 2
- In a binary tree of the same height, a full binary tree has the largest number of leaf nodes and the largest number of total nodes
- A full binary tree is always a true binary tree, and a true binary tree is not always a full binary tree
Assume the height of the full binary tree is h(h >= 1)
The number of nodes at layer I is: 2 ^ (i-1)
Number of leaf nodes: 2 ^ (H-1)
Total number of nodes n
N = 2^h – 1 = 2^0 + 2^1 + 2^2 +… + 2^(h – 1)
h = log2(n + 1)
2.5. Complete binary trees
- Complete binary tree: Nodes are numbered from top to bottom and from left to right. All their numbers can correspond to numbers in the full binary tree of the same height
- The leaf nodes only appear in the last 2 layers, with the last 1 layer of leaf nodes aligned to the left
- Complete binary tree A full binary tree from the root node to the penultimate level
- A full binary tree is always a complete binary tree, and a complete binary tree is not always a full binary tree
2.5.1. Properties of complete binary trees
- Nodes of degree 1 have only left subtrees
- Nodes of degree 1 are either 1 or 0
- A complete binary tree with the same number of nodes has the smallest height
2.6, binary tree traversal
2.6.1, preorder traversal
Address: leetcode-cn.com/problems/bi…
-
Access order: The root node is visited first, the left subtree is traversed first, and the right subtree is traversed before
Public void preorderTraversal() {preorderTraversal(root); } private void preorderTraversal(Node node) { if (node == null) return; System.out.println(node.element); preorderTraversal(node.left); preorderTraversal(node.right); }
// Non-recursive, using a stack implementation
class Solution { public List preorderTraversal(TreeNode root) { List res = new ArrayList(); preorder(root, res); return res; }
public void preorder(TreeNode root, List<Integer> res) { if (root == null) { return; } res.add(root.val); preorder(root.left, res); preorder(root.right, res); } Copy the code
}
2.6.2, middle-order traversal
Address: leetcode-cn.com/problems/bi…
-
Access order: traverses the left subtree first, then the root node, and finally the right subtree in middle order
Public void inorderTraversal() {inorderTraversal(root); } private void inorderTraversal(Node node) { if (node == null) return; inorderTraversal(node.left); // System.out.println(node.element); inorderTraversal(node.right); } class Solution {public List inorderTraversal(TreeNode root) {List res = new ArrayList(); Deque stk = new LinkedList(); while (root ! = null || ! stk.isEmpty()) { while (root ! = null) { stk.push(root); root = root.left; } root = stk.pop(); res.add(root.val); root = root.right; } return res; }}
2.6.3, post-order traversal
Address: leetcode-cn.com/problems/bi…
-
Access order: the left subtree is traversed first, the right subtree is traversed later, and the root node is visited last
Public void postorderTraversal() {postorderTraversal(root); } private void postorderTraversal(Node node) { if (node == null) return; postorderTraversal(node.left); postorderTraversal(node.right); System.out.println(node.element); } class Solution {public List postorderTraversal(TreeNode root) {List res = new ArrayList(); if (root == null) { return res; }
Deque<TreeNode> stack = new LinkedList<TreeNode>(); TreeNode prev = null; while (root ! = null || ! stack.isEmpty()) { while (root ! = null) { stack.push(root); root = root.left; } root = stack.pop(); if (root.right == null || root.right == prev) { res.add(root.val); prev = root; root = null; } else { stack.push(root); root = root.right; } } return res; }Copy the code
}
2.6.4, Sequence traversal
Address: leetcode-cn.com/problems/bi…
-
Each node is accessed from top to bottom and left to right
public void levelOrderTraversal() { if (root == null) return; Queue<Node<E>> Queue = new LinkedList<>(); Queue.offer (root); // Join queue. // If the queue is not empty, loop while (! Queue. IsEmpty ()) {// add a new Node<E> Node = queue. Poll (); System.out.println(node.element); If (node.left! = null) { queue.offer(node.left); } // If (node.right! = null) { queue.offer(node.right); }}}Copy the code
3. Binary search tree
3.1. Thinking: Search for an integer among the integers of n dynamic arrays to see if it exists?
- Suppose we use a dynamic array to store elements, and start the search from the 0th position. The average time complexity is O(n).
- If maintaining an ordered dynamic array, using binary search, the worst time complexity is: O(logn)
- But the average complexity of adding and removing is order n.
- For this requirement, we can use binary search tree optimization
3.2. What is a binary search tree
- Binary search tree is a binary tree, a very widely used binary tree, also known as: binary search tree, binary sorting tree
- The value of any node is greater than the value of all nodes in its left subtree
- The value of any node is less than the value of all nodes in its right subtree
- Its left and right subtrees are also binary trees
- Binary search tree can greatly improve the efficiency of searching data
3.3 interface design and implementation of binary search tree
3.3.1, Adding a Node
Find the parent node
Creating a new node
Parent. left = node or parent.right = node
Public void add(E element) {elementNotNullCheck(element); If (root == null) {root = new Node<>(element, null); size++; return; } Node<E> parent = root; Node<E> node = root; int cmp = 0; CMP = compare(element, node. Element); parent = node; If (CMP > 0) {node = node.right; } else if (CMP < 0) {// less than 0, put left node = node.left; } else {// equal node.element = element; return; } } while (node ! = null); Node<E> newNode = newNode <>(element, parent); If (CMP > 0) {// if (CMP > 0) {parent.right = newNode; } else {// Put the left node in the parent node parent.left = newNode; } size++; }Copy the code
3.3.2. Delete a node
Delete leaf node:
node == node.parent.left , node.parent.left = null
node == node.parent.right , node.parent.right = null
node.parent == null , root = null
- Delete the node whose degree is 1
Replace the position of the original node with a child node
Child is node. Left or child is node. Right
Replace node position with child
If node is the left child
child.parent = node.parent
node.parent.left = child
- If node is the right child node
child.parent = node.parent
node.parent.right = child
- If it’s the root node
root = child
child.parent = null
3. Delete the node whose degree is 2
The value of the original node is overwritten by the value of the precursor or successor node
Then, delete the corresponding precursor or successor node
Private void remove(Node<E> Node) {if (Node == null) return; size--; If (node.hastwochildren ()) {// Find the node <E> s = succeeded (node); Node. element = s.lement; // Delete the successor node node = s; } // Delete node (the degree of node must be 1 or 0) node <E> replacement = node.left! = null ? node.left : node.right; if (replacement ! = null) {// node is a node with degree 1 // change parent replacement. If (node.parent == null) {// Node is a node with degree 1 and is the root node. Root = replacement; } else if (node == node.parent.left) { node.parent.left = replacement; } else { // node == node.parent.right node.parent.right = replacement; }} else if (node.parent == null) {// node is a leaf node and a root node root = null; } else {if (node == node.parent. Left) {node.parent. Left = null; } else { // node == node.parent.right node.parent.right = null; }}}Copy the code
4. Balanced binary search tree
- Balancing a binary tree is essentially balancing the heights of the left and right subtrees of an ordinary binary tree
- When the number of nodes is fixed, the closer the height of the left and right subtrees are, the more balanced the binary tree will be
- Ideal balance: Like complete and full binary trees, the height is minimal
4.1. How to improve binary search tree?
- First, the order in which nodes are added and removed is unrestricted and can be considered random
- So after the node add, delete operation, try to make binary search tree restore balance
- If you continue to adjust the position of nodes, you can achieve the ideal balance, but the cost may be relatively large
- A more reasonable improvement plan is to achieve moderate balance with as few adjustment times as possible
- A moderately balanced binary tree can be called a balanced binary search tree
- The classic and common balanced binary search trees are: AVL tree, red black tree