树
树 是由n(n>=1)个有限节点组成一个具有层次关系的集合。它具有以下特点:每个节点有零个或多个子节点;没有父节点的节点称为 根 节点;每一个非根节点有且只有一个 父节点 ;除了根节点外,每个子节点可以分为多个不相交的子树。
二叉树基本概念
定义
二叉树是每个节点最多有两棵子树的树结构。通常子树被称作“左子树”和“右子树”。二叉树常被用于实现二叉查找树和二叉堆。
相关性质:
1)二叉树的每个结点至多只有2棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。
2)二叉树的第i层至多有2^(i-1)个结点;深度为k的二叉树至多有2^k-1个结点。
3)满二叉树:一棵深度为k,且有2^k-1个节点的二叉树
4)完全二叉树:完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。(编号方式是从左至右依次编号)
二叉树的遍历
1)广度遍历
广度遍历也叫层次遍历
2)深度遍历
(1) 先序遍历 若二叉树为空,则空操作,否则先访问根节点,再先序遍历左子树,最后先序遍历右子树。
(2) 中序遍历 若二叉树为空,则空操作,否则先中序遍历左子树,再访问根节点,最后中序遍历右子树。
(3) 后序遍历 若二叉树为空,则空操作,否则先后序遍历左子树访问根节点,再后序遍历右子树,最后访问根节点。
二叉树的实现
class Node(object):
def __init__(self, item):
self.elem = item
self.lchild = None
self.rchild = None
class Tree(object):
def __init__(self):
self.root = None
#添加节点
def add(self, item):
node = Node(item)
if self.root is None:
self.root = node
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
if cur_node.lchild is None:
cur_node.lchild = node
return
else:
queue.append(cur_node.lchild)
if cur_node.rchild is None:
cur_node.rchild = node
else:
queue.append(cur_node.rchild)
#广度遍历,或者层次遍历
def breadth_travel(self):
if self.root is None
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
print (cur_node.elem)
if cur_node.lchild is not None:
queue.append(cur_node.lchild)
if cur_node.rchild is not None:
queue.append(cur_node.rchild)
#先序遍历
def preorder(self, node):
if node == None:
return
print (node.elem)
self.preorder(node.lchild)
self.preorder(node.lchild)
#中序遍历
def midorder(self, node):
if node == None:
return
self.preorder(node.lchild)
print (node.elem)
self.preorder(node.lchild)
#后序遍历
def posorder(self, node):
if node == None:
return
self.preorder(node.lchild)
self.preorder(node.lchild)
print (node.elem)
二叉树查找树
二叉查找树就是二叉排序树,也叫二叉搜索树。二叉查找树或者是一棵空树,或者是具有下列性质的二叉树:
(1) 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2) 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3) 左、右子树也分别为二叉排序树;
(4) 没有键值相等的结点。
平衡二叉树
平衡二叉树又称AVL树
它或者是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。
红黑树
红黑树是平衡二叉树的一种,它保证在最坏情况下基本动态集合操作的事件复杂度为O(log n)。
红黑树和平衡二叉树区别如下:
(1) 红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单。
(2) 平衡二叉树追求绝对平衡,条件比较苛刻,实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能预知。