数据结构与算法之树形结构

二叉树

二叉树的节点的节点定义

在堆排序时曾经介绍了什么是二叉树,当时是用列表来实现的,但是二叉树可能出现空值,浪费空间,所以使用类似链表的存储结构。

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存储在硬盘里,用于数据库的索引。

猜你喜欢

转载自www.cnblogs.com/cuiyuanzhang/p/10512463.html