树(Tree)是有限个数据节点(即数据项)组成的集合,其中除根节点和叶的下标为外,每个节点都具有一个直接先驱节点和多个直接后继节点,这与每节点仅具有一个直接先驱节点和一个直接后继节点的线性结构不同;树结构中,根节点(Root)没有先驱节点,叶节点(Leaf)没有后续节点。
如果树中的每个节点最多可以有两个后续节点,那么这样的树状结构称为二叉树,这是树状结构中最为常用的一种。二叉树(Binary Tree)定义的操作如下:
代码实现:
Python语言中,树结构可基于链表或嵌套列表实现。
嵌套列表法的优点是:子树的结构与树相同,是一种递归数据结构;且很容易扩展到多叉树,仅需要增加列表元素即可。但时间复杂度较高,嵌套列表法中,子树节点插入操作借助python列表(list)数据类型的 pop(n) 方法和 insert(n) 方法实现,其时间复杂度是 O(n)。其它二叉树定义方法基于列表(list)索引实现,时间复杂度是 O(1)。
同样可以用节点链接法(链表)来实现树,每个节点保存根节点的数据项,以及指向左右子树的链接,其所有操作的时间复杂度都是 O(1)。
class BinaryTree(object):
"""
BinaryTree:创建一个二叉树节点;
insertLeft:将新节点插入树中作为其直接的左子节点;
insertRight:将新节点插入树中作为其直接的右子节点;
getRootVal:返回本节点的值;
setRootVal:设置本节点的值;
getLeftChild:返回左子树;
getRightChild:返回右子树。
"""
def __init__(self, key, val, left=None, right=None
, parent=None):
self.key = key
self.payload = val
self.leftChild = left
self.rightChild = right
self.parent = parent
def insertLeftChild(self, key, val, **kwargs):
if self.leftChild is None:
temp = BinaryTree(key, val, **kwargs)
temp.parent = self
self.leftChild = temp
else:
temp = BinaryTree(key, val, **kwargs)
self.leftChild.parent = temp
temp.leftChild = self.leftChild
temp.parent = self
self.leftChild = temp
def insertRightChild(self, key, val, **kwargs):
if self.rightChild is None:
temp = BinaryTree(key, val, **kwargs)
temp.parent = self
self.rightChild = temp
else:
temp = BinaryTree(key, val, **kwargs)
self.rightChild.parent = temp
temp.rightChild = self.rightChild
temp.parent = self
self.rightChild = temp
def getRoot(self):
return self.key, self.payload
def setRootVal(self, key, val):
self.key = key
self.payload = val
def getLeftChild(self):
return self.leftChild
def getRightChild(self):
return self.rightChild
对一个数据集中的所有数据项进行访问的操作称为遍历(Traversal),树的非线性特点,使得遍历操作较为复杂。按照对节点访问次序的不同,二叉树有三种常见遍历方式:
代码实现:
通过递归调用实现树的遍历十分简单,三种不同的遍历方式只需调整基本条件和递归调用的代码执行顺序即可。
# 二叉树前序遍历
def preorder(tree):
if tree is not None:
print(tree.payload)
if tree.leftChild is not None:
preorder(tree.leftChild)
if tree.rightChild is not None:
preorder(tree.rightChild)
# 二叉中序遍历
def inorder(tree):
if tree is not None:
if tree.leftChild is not None:
preorder(tree.leftChild)
print(tree.payload)
if tree.rightChild is not None:
preorder(tree.rightChild)
# 二叉树后序遍历
def postorder(tree):
if tree is not None:
if tree.leftChild is not None:
preorder(tree.leftChild)
if tree.rightChild is not None:
preorder(tree.rightChild)
print(tree.payload)
常见的二叉树类型有平衡二叉树(Balanced Binary Tree)、完全二叉树(Complete Binary Tree)、满二叉树(Full Binary Tree)和二叉查找树(Binary Search Tree,也称:二叉搜索树或二叉排序树)四类。其中,二叉查找树和完全二叉树一定是平衡二叉树,满二叉树是完全二叉树的一个特例。他们之间的关系,如下图所示: