1. BinaryTree (二叉树)
二叉树是有限个元素的集合,该集合或者为空、或者有一个称为根节点(root)的元素及两个互不相交的、分别被称为左子树和右子树的二叉树组成。
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。
二叉树的第i层至多有个结点
深度为k的二叉树至多有个结点;
对任何一棵二叉树T,如果其终端结点数为N0,度为2的结点数为N2,则N0=N2+1
二叉树的遍历分为以下三种:
先序遍历:遍历顺序规则为【根左右】
中序遍历:遍历顺序规则为【左根右】
后序遍历:遍历顺序规则为【左右根】
什么是【根左右】?就是先遍历根,再遍历左孩子,最后遍历右孩子;
举个例子,看下图(图从网上找的):
先序遍历:ABCDEFGHK
中序遍历:BDCAEHGKF
后序遍历:DCBHKGFEA
以中序遍历为例:
中序遍历的规则是【左根右】,我们从root节点A看起;
此时A是根节点,遍历A的左子树;
A的左子树存在,找到B,此时B看做根节点,遍历B的左子树;
B的左子树不存在,返回B,根据【左根右】的遍历规则,记录B,遍历B的右子树;
B的右子树存在,找到C,此时C看做根节点,遍历C的左子树;
C的左子树存在,找到D,由于D是叶子节点,无左子树,记录D,无右子树,返回C,根据【左根右】的遍历规则,记录C,遍历C的右子树;
C的右子树不存在,返回B,B的右子树遍历完,返回A;
至此,A的左子树遍历完毕,根据【左根右】的遍历规则,记录A,遍历A的右子树;
A的右子树存在,找到E,此时E看做根节点,遍历E的左子树;
E的左子树不存在,返回E,根据【左根右】的遍历规则,记录E,遍历E的右子树;
E的右子树存在,找到F,此时F看做根节点,遍历F的左子树;
F的左子树存在,找到G,此时G看做根节点,遍历G的左子树;
G的左子树存在,找到H,由于H是叶子节点,无左子树,记录H,无右子树,返回G,根据【左根右】的遍历规则,记录G,遍历G的右子树;
G的右子树存在,找到K,由于K是叶子节点,无左子树,记录K,无右子树,返回G,根据【左根右】的遍历规则,记录F,遍历F的右子树;
F的右子树不存在,返回F,E的右子树遍历完毕,返回A;
至此,A的右子树也遍历完毕;
最终我们得到上图的中序遍历为BDCAEHGKF,无非是按照遍历规则来的;
2、二叉树遍历实现(Python)
假设我们又二叉树:(我们实现他的先序中序后序分层遍历)
import math
#定义二叉树
class BTNode(object):
"""docstring for BTNode"""
def __init__(self, data):
self.data = data
self.leftChild = None
self.rightChild = None
# 插入元素
def InsertElementBinaryTree(root, node):
if root:
if node.data < root.data:
if root.leftChild:
InsertElementBinaryTree(root.leftChild, node)
else:
root.leftChild = node
else:
if root.rightChild:
InsertElementBinaryTree(root.rightChild, node)
else:
root.rightChild = node
else:
return 0
# 初始化二叉树
def InitBinaryTree(dataSource, length):
root = BTNode(dataSource[0])
for x in range(1,length):
node = BTNode(dataSource[x])
InsertElementBinaryTree(root, node)
return root
print('Done...')
# 先序
def PreorderTraversalBinaryTree(root):
#递归调用
if root:
print('%d | ' % root.data,)
PreorderTraversalBinaryTree(root.leftChild)
PreorderTraversalBinaryTree(root.rightChild)
# 中序
def InorderTraversalBinaryTree(root):
if root:
InorderTraversalBinaryTree(root.leftChild)
print('%d | ' % root.data,)
InorderTraversalBinaryTree(root.rightChild)
# 后序
def PostorderTraversalBinaryTree(root):
if root:
PostorderTraversalBinaryTree(root.leftChild)
PostorderTraversalBinaryTree(root.rightChild)
print ('%d | ' % root.data,)
# 分层
def TraversalByLayer(root, length):
stack = []
stack.append(root)
for x in range(length):
node = stack[x]
print('%d | ' % node.data,)
if node.leftChild:
stack.append(node.leftChild)
if node.rightChild:
stack.append(node.rightChild)
if __name__ == '__main__':
dataSource = [3, 4, 2, 6, 7, 1, 8, 5]
length = len(dataSource)
BTree = InitBinaryTree(dataSource, length)
print('****NLR:')
PreorderTraversalBinaryTree(BTree)
print('\n****LNR')
InorderTraversalBinaryTree(BTree)
print('\n****LRN')
PostorderTraversalBinaryTree(BTree)
print('\n****LayerTraversal')
TraversalByLayer(BTree, length)