由于树可以转换为二叉树,故直接进行二叉树的学习。
二叉树
二叉树最多只有左子树和右子树两个子树,二叉树的性质如下:
- 在二叉树的第 i i i层最多有 2 i − 1 2^{i-1} 2i−1个节点
- 深度为 k k k的二叉树最多有 2 k − 1 2^{k-1} 2k−1个节点
- 对于任意一棵二叉树,如果叶节点数为 N 0 N_{0} N0,而度数为2的节点总数为 N 2 N_{2} N2,则有 N 0 = N 2 + 1 N_0 = N_2 + 1 N0=N2+1
- 具有 n n n个节点的完全二叉树的深度必为 log 2 ( n + 1 ) \log2(n+1) log2(n+1)
- 对完全二叉树,若从上至下、从左至右编号,则编号为 i i i的结点,其左孩子编号必为 2 i + 1 2i + 1 2i+1,其右孩子编号必为 2 i + 2 2i+2 2i+2;其双亲的编号必为 ( i − 1 ) / 2 (i - 1)/2 (i−1)/2(除 i = 1 i=1 i=1外)
常用的二叉树有满二叉树和完全二叉树,满二叉树指除最后一层无任何子节点外,每一层上的所有结点都有两个子结点二叉树;完全二叉树指当二叉树的深度为 h h h,除第 h h h 层外,其它各层 ( 1 ∼ h − 1 ) (1 \sim h-1) (1∼h−1) 的结点数都达到最大个数,第 h h h 层所有的结点都连续集中在最左边的二叉树。
满二叉树
完全二叉树
二叉树的实现:
from collection import deque
# 二叉树结点
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
# 二叉树
class Tree(object):
def __init__(self):
self.root = None
二叉树层序遍历:若树为空,则返回空,zh否则从根节点开始访问,从上而下逐层遍历。在同一层中按从左到右的顺序对节点逐个访问。若二叉树如下所示,则层序遍历的顺序为:ABCDEFGHI。
# 层序遍历
def bfs(self, root):
if not root: return []
queue = [root]
res = []
while queue:
nextLayer = []
for node in queue:
res.append(node.val)
if node.left:
nextLayer.append(node.left)
if node.right:
nextLayer.append(node.right)
queue = nextLayer
return res
二叉树前序遍历:若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。若二叉树如上图所示,遍历的顺序为:ABDGHCEIF。
# 递归法
def getPreOrder(root):
res = []
def preOrderRec(root):
if not root: return []
res.append(root.val)
preOrderRec(root.left)
preOrderRec(root.right)
getPreOrder(root)
return res
# 迭代法
def preOrderIter(root):
if not root: return []
stack = [root]
res = []
while stack:
root = stack.pop()
if root:
res.append(root.val)
if root.right:
stack.append(root.right)
if root.left:
stack.append(root.left)
return res
二叉树中序遍历:若树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树。若二叉树如上图图所示,遍历的顺序为:GDHBAEICF。
中序遍历的结果一个很重要的特性:遍历结果自然就是升序的。
# 递归法
def getInOrder(root):
res = []
def inOrderRec(root):
if not root: return []
inOrderRec(root.left)
res.append(root.val)
inOrderRec(root.right)
inOrderRec(root)
return res
# 迭代法
def inOrderIter(root):
if not root: return []
stack = []
res = []
while stack or root:
if root:
stack.append(root)
root = root.left
else:
node = stack.pop()
res.append(node.val)
root = node.right
return res
二叉树后序遍历:若树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访向左右子树,最后是访问根结点。若二叉树如上图所示,遍历的顺序为:GHDBIEFCA。
def getPostOrder(self, root):
res = []
def postOrderRec(root):
if not root: return []
postOrderRec(root.left)
postOrderRec(root.right)
res.append(root.val)
def postOrderIter(root):
if not root: return []
stack = [root]
res = []
while stack:
node = stack.pop()
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
res.append(node.val)
return res
根据前序遍历和中序遍历重建二叉树
df construct_tree(preorder=None, inorder=None):
if not preorder or not inorder:
return None
index = inorder.index(preorder[0])
# 左子树的中序遍历序列
left = inorder[0:index]
# 右子树的中序遍历序列
right = inorder[index+1:]
# 返回根节点
root = TreeNode(preorder[0])
# 递归调用重建二叉树
root.left = construct_tree(preorder[1:1+len(left)], left)
root.right = construct_tree(preorder[-len(right):], right)
return root
完整实验代码
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def __init__(self):
self.res = []
def getPreOrder(self, root):
# 递归法
def preOrderRec(root):
if not root:
return None
self.res.append(root.val)
preOrderRec(root.left)
preOrderRec(root.right)
# 迭代法
def preOrderIter(root):
if not root: self.res = []
stack = [root]
while stack:
root = stack.pop()
if root:
self.res.append(root.val)
if root.right:
stack.append(root.right)
if root.left:
stack.append(root.left)
# preOrderRec(root)
preOrderIter(root)
def getInOrder(self, root):
def inOrderRec(root):
if not root:
return None
inOrderRec(root.left)
self.res.append(root.val)
inOrderRec(root.right)
def inOrderIter(root):
if not root: self.res = []
stack = []
while stack or root:
if root:
stack.append(root)
root = root.left
else:
node = stack.pop()
self.res.append(node.val)
root = node.right
# inOrderRec(root)
inOrderIter(root)
def getPostOrder(self, root):
def postOrderRec(root):
if not root:
return None
postOrderRec(root.left)
postOrderRec(root.right)
self.res.append(root.val)
def postOrderIter(root):
if not root: self.res = []
stack = [root]
while stack:
node = stack.pop()
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
self.res.append(node.val)
# postOrderRec(root)
postOrderIter(root)
def bfs(self, root):
if not root: self.res = []
queue = [root]
while queue:
nextLayer = []
for node in queue:
self.res.append(node.val)
if node.left:
nextLayer.append(node.left)
if node.right:
nextLayer.append(node.right)
queue = nextLayer
if __name__ == "__main__":
node1 = TreeNode('A')
node2 = TreeNode('B')
node3 = TreeNode('C')
node4 = TreeNode('D')
node5 = TreeNode('E')
node6 = TreeNode('F')
node7 = TreeNode('G')
node8 = TreeNode('H')
node9 = TreeNode('I')
node1.left = node2
node1.right = node3
node2.left = node4
node4.left = node7
node4.right = node8
node3.left = node5
node3.right = node6
node5.right = node9
s = Solution()
# s.getPreOrder(node1)
# print (s.res) # ['A', 'B', 'D', 'G', 'H', 'C', 'E', 'I', 'F']
# s.getInOrder(node1)
# print (s.res) # ['G', 'D', 'H', 'B', 'A', 'E', 'I', 'C', 'F']
# s.getPostOrder(node1)
# print (s.res[::-1]) # ['G', 'H', 'D', 'B', 'I', 'E', 'F', 'C', 'A']
# s.bfs(node1)
# print (s.res) # ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
Java实现代码:
import java.util.*;
/**
* @Author dyliang
* @Date 2020/10/7 21:22
* @Version 1.0
*/
public class BinaryTree {
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.left.left.left = new TreeNode(8);
root.left.left.right = new TreeNode(9);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(7);
System.out.println("---------recursive---------");
preOrderRecur(root);
System.out.println();
System.out.println("---------------------");
inOrderRecur(root);
System.out.println();
System.out.println("---------------------");
postOrderRecur(root);
System.out.println();
System.out.println("---------Iteration---------");
preOrderIter(root);
System.out.println();
System.out.println("---------------------");
inOrderIter(root);
System.out.println();
System.out.println("---------------------");
postOrderIter(root);
System.out.println();
System.out.println("---------------------");
levelOrder(root);
/**
* ---------recursive---------
* 1 2 4 8 9 5 3 6 7
* ---------------------
* 8 4 9 2 5 1 6 3 7
* ---------------------
* 8 9 4 5 2 6 7 3 1
* ---------Iteration---------
* 1 2 4 8 9 5 3 6 7
* ---------------------
* 8 4 9 2 5 1 6 3 7
* ---------------------
* 8 9 4 5 2 6 7 3 1
* ---------------------
* 1 2 3 4 5 6 7 8
*/
}
public static class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
public TreeNode() {
}
}
/**
* 递归方式的先序遍历
* @param root
*/
public static void preOrderRecur(TreeNode root){
if(root == null){
return;
}
System.out.print(root.val + " ");
preOrderRecur(root.left);
preOrderRecur(root.right);
}
/**
* 递归方式的中序遍历
* @param root
*/
public static void inOrderRecur(TreeNode root){
if(root == null){
return;
}
inOrderRecur(root.left);
System.out.print(root.val + " ");
inOrderRecur(root.right);
}
/**
* 递归方式的后续遍历
* @param root
*/
public static void postOrderRecur(TreeNode root){
if(root == null){
return;
}
postOrderRecur(root.left);
postOrderRecur(root.right);
System.out.print(root.val + " ");
}
/**
* 迭代方式的先序遍历
* @param root
*/
public static void preOrderIter(TreeNode root){
if(root == null){
return;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
System.out.print(node.val + " ");
if(node.right != null){
stack.push(node.right);
}
if(node.left != null){
stack.push(node.left);
}
}
}
/**
* 迭代方式的后序遍历
* @param root
*/
public static void postOrderIter(TreeNode root){
if(root == null){
return;
}
Stack<TreeNode> stack = new Stack<>();
List<Integer> list = new ArrayList<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node = stack.pop();
list.add(node.val);
if(node.left != null){
stack.push(node.left);
}
if(node.right != null) {
stack.push(node.right);
}
}
Collections.reverse(list);
for (Integer i : list) {
System.out.print(i + " ");
}
}
/**
* 迭代方式的中序遍历
* @param root
*/
public static void inOrderIter(TreeNode root){
if(root == null){
return;
}
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || root != null){
if(root != null){
stack.push(root);
root = root.left;
} else {
root = stack.pop();
System.out.print(root.val + " ");
root = root.right;
}
}
}
/**
* 层序遍历
* @param root
*/
public static void levelOrder(TreeNode root){
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()){
Queue<TreeNode> next = new LinkedList<>();
for (TreeNode node : queue) {
if(node != null){
System.out.print(node.val + " ");
if(root.left != null){
next.add(node.left);
}
if(root.right != null){
next.add(node.right);
}
}else{
return;
}
}
queue = next;
}
}
}