1、基本概念
二叉树 是一种简单的树形结构,是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树是一种递归结构。
二叉树的基本概念
- 空树:不包含任何节点的二叉树成为空树。只包含一个节点的二叉树称为一个单点树。
- 父节点和子节点:一颗二叉树的根节点称为该数的子树根节点的父节点,与之对应的,子数的根节点称为二叉树树根节点的子节点。注意父节点和子节点是相对的。
- 叶子节点:在二叉树中没有子节点的节点称为叶子节点。
- 分支节点:只有存在子节点的节点都是分之节点。
- 度数:一个节点的子节点的个数称为该节点的度数。即 叶子节点的度数永远为0,分之节点的度数为1或2。
- 二叉树的层:二叉树是一种层次结构,根节点称为二叉树的0层,从根节点到任一节点的路径长度就是该节点所在的层数,也称为该节点的层数。
- 二叉树的高度:也称为深度,就是树中节点的最大层数。
二叉树的性质
- 性质1: 在二叉树的第i层上至多有2^(i-1)个结点(i>0)
- 性质2: 高度为h的二叉树至多有2^h - 1个结点(h>0)
- 性质3: 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
- 性质4:具有n个结点的完全二叉树的深度必为 log2(n+1)
- 性质5:对完全二叉树,若从上至下、从左至右编号,则编号为i 的结点,其左孩子编号必为2i,其右孩子编号必为2i+1;其双亲的编号必为i/2(i=1 时为根,除外)
满二叉树:如果二叉树中所有分支节点的度数都是2,这样的二叉树称为满二叉树。
完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
二叉树的遍历:
深度优先遍历:
深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
那么深度遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。
这三种遍历分别叫做先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)。
先序遍历:在先序遍历中,先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树。即 根节点->左子树->右子树
中序遍历:在中序遍历中,递归使用中序遍历访问左子树,然后访问根节点,最后再递归使用中序遍历访问右子树。即 左子树->根节点->右子树
后序遍历:在后序遍历中,先递归使用后序遍历访问左子树和右子树,最后访问根节点。即 左子树->右子树->根节点
广度优先遍历:
是按路径长度由近到远地访问节点。也就是按二叉树的层次逐层访问树中各个节点,这种遍历不能写成一个递归过程。
2、二叉树基于Python 列表的简单实现
# 二叉树基于Python语言list的实现
class BinTreeListWay(object):
"""
二叉树类
"""
def __init__(self, data, left=None, right=None):
self.__bintree = [data,left, right]
def is_empty(self):
"""
判断二叉树是否为空
"""
return self.__bintree == None
def root(self):
"""
返回根节点
"""
return self.__bintree[0]
def left(self):
return self.__bintree[1]
def right(self):
return self.__bintree[2]
def set_root(self, data):
"""
设置根节点
"""
self.__bintree[0] = data
def set_left(self, data):
self.__bintree[1] =data
def set_right(self, data):
self.__bintree[2] = data
def show(self):
"""
返回二叉树
"""
return self.__bintree
if __name__ == "__main__":
d_tree = BinTreeListWay('D', 'F', 'G')
e_tree = BinTreeListWay('E', 'I', 'H')
c_tree = BinTreeListWay('C', d_tree.show(), e_tree.show())
a_tree = BinTreeListWay('A', 'B')
a_tree.set_right(c_tree.show())
print(a_tree.show())
3、二叉树基于Python自建类的实现
# 二叉树基于Python语言面自建类的实现
class Node(object):
"""
节点类
"""
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
class BinTreeClassWay(object):
"""
二叉树类
"""
def __init__(self, root=None):
self.root = root
def is_empty(self):
"""
判断二叉树是否为空
"""
return self.root == None
def add(self, data):
"""
添加节点,此方法无法控制将节点挂在到那颗子树,也就意味着它最终形成的二叉树为完全二叉树或满二叉树
"""
# 实例化一个新的节点对象
node = Node(data)
# 如果树是空的,则对根节点数据元素赋值
if self.root == None:
self.root = node
else:
# 创建一个存放节点的队列
queue = []
queue.append(self.root)
# 对已有的节点按层次进行遍历
while queue:
# 弹出队列的第一个节点
head = queue.pop(0)
if head.left == None:
head.left = node
return
elif head.right == None:
head.right = node
return
else:
#如果左右子树都不为空,加入队列继续判断
queue.append(head.left)
queue.append(head.right)
# 基于深度优先遍历
def preorder(self, bin_tree):
"""
先序遍历方法: 根节点->左子树->右子树
"""
if bin_tree == None:
return
print(bin_tree.data)
self.preorder(bin_tree.left)
self.preorder(bin_tree.right)
# 基于深度优先遍历
def inorder(self, bin_tree):
"""
中序遍历方法: 左子树->根节点->右子树
"""
if bin_tree == None:
return
self.preorder(bin_tree.left)
print(bin_tree.data)
self.preorder(bin_tree.right)
# 基于深度优先遍历
def postorder(self, bin_tree):
"""
后序遍历方法: 左子树->右子树->根节点
"""
if bin_tree == None:
return
self.preorder(bin_tree.left)
self.preorder(bin_tree.right)
print(bin_tree.data)
# 基于广度优先遍历
def breadth_first_travel(self, bin_tree):
"""
广度优先遍历
"""
if bin_tree == None:
return
# 该方法和 add 方法中的插入元素类似
queue = []
queue.append(bin_tree)
while queue:
node = queue.pop(0)
print(node.data)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
def show(self):
"""
返回二叉树
"""
return self.root
if __name__ == "__main__":
bin_tree = BinTreeClassWay()
bin_tree.add('A')
bin_tree.add('B')
bin_tree.add('C')
bin_tree.add('D')
bin_tree.add('E')
bin_tree.add('F')
bin_tree.add('G')
print('先序遍历')
bin_tree.preorder(bin_tree.show())
print('中序遍历')
bin_tree.inorder(bin_tree.show())
print('后序遍历')
bin_tree.postorder(bin_tree.show())
print('广度优先遍历')
bin_tree.breadth_first_travel(bin_tree.show())