二叉树
二叉树的节点的节点定义
在堆排序时曾经介绍了什么是二叉树,当时是用列表来实现的,但是二叉树可能出现空值,浪费空间,所以使用类似链表的存储结构。
class BiTreeNode:
def __init__(self,data):
self.data=data
self.lchild=None
self.rchild=Node
二叉树的遍历
二叉树的遍历有两类四种:
- 深度优先:前序遍历,中序遍历,后序遍历。
- 对于有两个遍历求二叉树的方法:前序找根节点(根在前面),中序找左右子树,后序找根节点(根在后面)
#前序遍历,root为根节点
def pre_order(root):
if root:
print(root.data,end = '')
pre_order(root.lchild)
pre_order(root.rchild)
#中序遍历,如果lchild没值则出栈
def in_order(root):
if root:
pre_order(root.lchild)
print(root.data,end = '')
pre_order(root.rchild)
#后序遍历,如果rchild没值则出栈
def post_order(root):
if root:
pre_order(root.lchild)
pre_order(root.rchild)
print(root.data,end = '')
- 广度优先:层次遍历
#根据队列实现
def level_order(root):
q=deque()
q.append(root)
while(len(q)>0):
x=q.popleft()
print(x.data,end='')
if x.lchild():
q.append(x.lchild)
if x.rchild():
q.append(x.rchild)
二叉搜索树
相关知识点
二叉搜索树,也叫二叉排序树,它要求每一个节点左子树的节点都比它小,右子树的节点都比他大。
- 二叉搜索树的遍历是升序序列
- 如果y是x左子树的一个节点,那么y.key <=x.key;
- 如果y是x右子树的一个节点,那么y.key >= x.key;
二叉搜索树的插入
class BST:
def __init__(self):
self.root=None #空不是根节点 而是None
def insert(self,key):
if not self.root:
self.root = BiTreeNode(key)
else:
p=self.root
while p:
if key < p.data: #分为左子树是否为空的情况
if p.lchild: #左子树有节点就在左子树继续查找,否则就插入左节点的位置
p = p.lchild
else:
p.lchild = BiTreeNode(key)
if key < p.data: #分为左子树是否为空的情况
elif key > p.data:
if p.rchild:
p = p.rchild
else:
p.lchild = BiTreeNode(key)
break
else:
break
二叉搜索树的查找
def query(self,key):
p = self.root
while p :
if key < p.data:
p = p.lchild
elif key >p.data:
p=p.rchild
else:
return True
return False
二叉搜索树的删除
删除有三种情况:
- 如果要删除的节点是叶子节点,那么找到后直接删除。
- 如果要删除的节点有一个子节点点,将 此节点的父节点和子节点相连接,然后删除此节点。
- 如果删除的节点有两个子节点,找到其左子树最大的节点或者右子树的最小节点,删除并替换当前节点,若最后一个一个节点还有一个右子节点,那么再按照第二种情况处理。
二叉搜索树的效率和AVL树
平均情况下,二叉搜索时的时间复杂度为O(logn),但是二叉搜索树可能会出现偏斜的情况,需要采用随机打乱的方法,所以这时候采用AVL树(自动平衡树)。
相关知识点:
AVL树:AVL树是一棵自平衡的二叉搜索树,它具有以下性质:
- 根的左右子树高度之差的绝对值不能超过1.
- 计算方法:
- 每个节点的左右子树的深度之差,也就是平衡因子。
- 根的左右子树都是平衡二叉树。
AVL树的插入操作
插入一个节点可能会造成AVL树的不平衡,可以通过旋转操作来修正。
插入一个节点后,只有从插入节点到根节点的路径上的节点的平衡可能被改变,需要找到第一个平衡条件的节点,称之为K,K的两棵子树高度差肯定为2.
不平衡的出现有四种情况:
- 不平衡是由于对K的右子节点的右子树插入导致的:左旋。
- 不平衡是由于对K的左子节点的左子树插入导致的:右旋。
- 不平衡是由于右子节点的左子树插入导致的:右旋->左旋。
- 不平衡是由于左子节点的右子树插入导致的:左旋->右旋。
B树
B-Tree是一种自平衡的多路搜索树,B-Tree存储在硬盘里,用于数据库的索引。