Niuke video summary 5
Binary tree first order, middle order and second order traversal
First order traversal: first print the current node, then print the whole left subtree, and then print the right subtree
Middle order traversal: first print the left node, then the current node, and then the right node
Post order traversal: print the left node first, then the right node, and finally the current node
Recursive Method
Take middle order traversal as an example. For first order traversal, append is put in front, and for subsequent traversal, append is put behind
# class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution(object): def inorderTraversal(self, root): """ :type root: TreeNode :rtype: List[int] """ result = [] def find(root): if root == None: return; else: find(root.left) result.append(root.val) find(root.right) find(root) return result
Non recursive method
Middle order traversal: establish a stack structure
If the current node is not empty, press one into the stack and the current node moves to the left
If the current node is empty, take one out of the stack and the current node goes to the right
# class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Stack(object): def __init__(self): self.stack = [] def push(self, x): self.stack.append(x) def pop(self): tem = self.stack[-1] self.stack = self.stack[0:-1] return tem def isEmpty(self): return len(self.stack)==0 class Solution(object): def inorderTraversal(self, root): """ :type root: TreeNode :rtype: List[int] """ stack = Stack() result = [] while (root!=None) or (not stack.isEmpty()): if root != None: stack.push(root) root = root.left else: root = stack.pop() result.append(root.val) root = root.right return result
Preorder traversal (left and right):
- head out of stack
- The right subtree is not empty and cannot be compressed
- The left subtree is not empty, so it is compressed
# class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Stack(object): def __init__(self): self.stack = [] def push(self, x): self.stack.append(x) def pop(self): tmp = self.stack[-1] self.stack = self.stack[0:-1] return tmp def isEmpty(self): return len(self.stack)==0 class Solution(object): def preorderTraversal(self, root): """ :type root: TreeNode :rtype: List[int] """ stack = Stack() result = [] while root!=None or not stack.isEmpty(): if root != None: result.append(root.val) stack.push(root.right) stack.push(root.left) root = stack.pop() return result
Post order traversal (left and right middle):
- head out of stack
- The left subtree is not empty, so it is compressed
- The right subtree is not empty and cannot be compressed
- First, it becomes the format of middle right and left, and then it is put into another stack to output left and right
# class TreeNode(object): # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Stack(object): def __init__(self): self.stack = [] def push(self, x): self.stack.append(x) def pop(self): tmp = self.stack[-1] self.stack = self.stack[0:-1] return tmp def isEmpty(self): return len(self.stack)==0 class Solution(object): def postorderTraversal(self, root): """ :type root: TreeNode :rtype: List[int] """ stack = Stack() result = [] stack_help = Stack() while root!=None or not stack.isEmpty(): if root != None: stack_help.push(root) stack.push(root.left) stack.push(root.right) root = stack.pop() while not stack_help.isEmpty(): result.append(stack_help.pop().val) return result
Successor node / pioneer node of binary tree
Successor node
During the middle order traversal, the next node of the node is called the successor node, and the previous node is called the pioneer node, which has one more parent pointer than the ordinary binary tree.
- If a node X has a right subtree, the successor node is the leftmost node of the right subtree
- If x has no right subtree, judge which tree x is the last node of the left subtree: X is the right child of the parent node, and then look up until a node is the left child of the parent node; X is the left child of the parent node, and the parent node is the successor node
Precursor node
- If a node X has a left subtree, the precursor node is the rightmost node of the left subtree
- If x has no left child tree, judge which tree x is the right child: X is the left child of the parent node, and then look up until a node is the right child of the parent node; X is the right child of the parent node, and the parent node is the precursor node
Serialization and deserialization of binary tree
# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Queue(object): def __init__(self): self.queue = [] def push(self,x): self.queue.append(x) def pop(self): tmp = self.queue[0] self.queue = self.queue[1:] return tmp def isEmpty(self): return len(self.queue)==0 class Codec: def serialize(self, root): """Encodes a tree to a single string. :type root: TreeNode :rtype: str """ result = '' queue = Queue() while root!=None or not queue.isEmpty(): if root!=None: queue.push(root.left) queue.push(root.right) result += (str(root.val) + ',') else: result += 'null,' root = queue.pop() result += 'null' return result def deserialize(self, data): """Decodes your encoded data to tree. :type data: str :rtype: TreeNode """ result = data.split(',') if result[0] == 'null': return [] for i in range(len(result)): if result[i] != 'null': result[i] = TreeNode(val=result[i]) nums_null = 0 node = result[0] cur_node = node for i in range(len(result)): cur_node = result[i] if cur_node!= 'null': if result[2*i+1-2*nums_null] != 'null': cur_node.left = result[2*i+1-2*nums_null] if result[2*i+2-2*nums_null] != 'null': cur_node.right = result[2*i+2-2*nums_null] else: nums_null += 1 return node # Your Codec object will be instantiated and called as such: # ser = Codec() # deser = Codec() # ans = deser.deserialize(ser.serialize(root))
Judge whether the binary tree is a balanced binary tree (tree DP)
Small routine (height): with recursive function, it will return to a node 3 times
Question: judge whether the whole tree with each node as the head is balanced
- Is the left tree balanced
- Is the right tree balanced
- Height of left tree
- Height of right tree
Judge whether the binary tree is a search binary tree
Search Binary Tree: the left node of each node is smaller than the current value, and the right node is larger than the current value
A: if the result of medium order traversal is in ascending order, it is a search binary tree
class Solution(object): def isValidBST(self, root): """ :type root: TreeNode :rtype: bool """ result = [] def findInOrder(root): if root == None: return; findInOrder(root.left) result.append(root.val) findInOrder(root.right) findInOrder(root) for i in range(len(result)-1): if result[i]>=result[i+1]: return False return True
Judge whether the binary tree is a complete binary tree
- If a node has a right child and no left child, it directly returns false
- If the left and right children of a node are incomplete (left and right / left and right), the nodes encountered later are leaf nodes
Complete binary tree, find the number of nodes
Full binary tree (layer L), number of nodes 2 L ā 1 2^L-1 2Lā1
- First traverse the left boundary and record the depth h
- Then traverse the left boundary of the right subtree: if the depth is h, it is proved that the left subtree is full, then recursion of the right subtree is OK; If the depth is H-1, it is proved that the right subtree is full (depth h-1), then the recursive left subtree is OK