数据结构,二叉排序树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构,二叉排序树相关的知识,希望对你有一定的参考价值。

二叉排序树(Binary Sort Tree),首先它是一棵树,“二叉”这个描述已经很明显了,就是树上的一根树枝开两个叉,于是递归下来就是二叉树了(下图所示),而这棵树上的节点是已经排好序的,具体的排序规则如下:

    若左子树不空,则左子树上所有节点的值均小于它的根节点的值

    若右子树不空,则右字数上所有节点的值均大于它的根节点的值

    它的左、右子树也分别为二叉排序数(递归定义)

    从图中可以看出,二叉排序树组织数据时,用于查找是比较方便的,因为每次经过一次节点时,最多可以减少一半的可能,不过极端情况会出现所有节点都位于同一侧,直观上看就是一条直线,那么这种查询的效率就比较低了,因此需要对二叉树左右子树的高度进行平衡化处理,于是就有了平衡二叉树(Balenced Binary Tree)

    所谓“平衡”,说的是这棵树的各个分支的高度是均匀的,它的左子树和右子树的高度之差绝对值小于1,这样就不会出现一条支路特别长的情况。于是,在这样的平衡树中进行查找时,总共比较节点的次数不超过树的高度,这就确保了查询的效率(时间复杂度为O(logn))

参考技术A 解:
(1)j节点,平衡因子为左子树3-右子树1=2,L节点,平衡因子为左子树4-右子树2 = 2,e节点,
平衡因子为左子树3-右子树5=-2
(2)在j做子树的右子树插入了h,导致树不平衡,所以是左右类型的不平衡树
(3)其调整方法是先围着g左旋,然后围着J右旋,调整为如下:
e
/ \
b l
/ \ / \
a d i n
/ / \ /
c g j m
/ \ \
f h k
指针变化为:L的左子树变为i,i左子树变为g右子树变为j,j左子树为NULL,g右子树变为h

Python描述数据结构之二叉排序树篇

前言

  本篇章主要介绍二叉树的应用之一------二叉排序树,包括二叉排序树的定义、查找、插入、构造、删除及查找效率分析。

1. 二叉排序树的定义

  二叉排序树 ( B i n a r y (Binary (Binary S o r t Sort Sort T r e e , B S T ) Tree,BST) Tree,BST),也称为二叉查找树,具有以下性质:
  (1) 若左子树非空,则左子树上所有结点的值均小于根结点的值;
  (2) 若右子树非空,则右子树上所有结点的值均大于根结点的值;
  (3) 左、右子树也分别是一棵二叉排序树。
  综上可知,在二叉排序树中:左子树结点的值 < 根结点的值 < 右子树结点的值,所以对二叉排序树进行中序遍历,可以得到一个递增的有序序列。

2. 二叉排序树的查找

  二叉排序树的查找是从根结点开始,沿某个分支逐层向下比较的过程。若二叉排序树非空,先将给定的关键字与根结点的关键字进行比较,若相等,则查找成功;若不相等,如果小于根结点的关键字,则在根结点的左子树上查找,如果大于根结点的关键字,则在根结点的右子树上查找。
  二叉排序树的查找算法:

    def BSTSearch(self, k):
        TreeNode = self.RootNode
        while TreeNode is not None and k != TreeNode.data:
            if k < TreeNode.data:
                TreeNode = TreeNode.lchild
            else:
                TreeNode = TreeNode.rchild
        return TreeNode

3. 二叉排序树的插入

  二叉排序树作为一种动态树表,它的结构通常不是一次生成的,而是在查找过程中,当树中不存在关键字等于给定值的结点时插入的。
  插入过程如下:若二叉排序树为空,则直接插入结点;若非空,先将给定的关键字与根结点的关键字进行比较,若小于根结点的关键字,则插入左子树,若大于根结点的关键字,则插入右子树。插入的结点一定是一个新添加的叶结点,且是查找失败时的查找路径上访问的最后一个结点的左孩子或右孩子。
  二叉排序树的插入算法:

    def BSTInsert(self, k):
        TreeNode = self.RootNode
        if TreeNode is None:
            self.RootNode = BiTreeLinkNode(k)
            return True
        while True:
            if k < TreeNode.data:
                if TreeNode.lchild is None:
                    TreeNode.lchild = BiTreeLinkNode(k)
                    return True
                TreeNode = TreeNode.lchild
            elif k > TreeNode.data:
                if TreeNode.rchild is None:
                    TreeNode.rchild = BiTreeLinkNode(k)
                    return True
                TreeNode = TreeNode.rchild
            else:
                return False

4. 二叉排序树的构造

  二叉排序树的构造过程如下:从一棵空树出发,依次输入元素,将它们插入树中的合适位置。关键字的序列不同,构造出来的二叉排序树也会有所不同,比如下图:

在这里插入图片描述

  二叉排序树的构造算法:

    def CreateBST(self):
        for val in self.data_list:
            self.BSTInsert(val)
        return self.RootNode

5. 二叉排序树的删除

  在二叉排序树中删除一个结点时,不能把以该结点为根的子树上的结点都删除,必须先把被删除的结点从存储二叉排序树的链表上摘下,将因删除结点而断开的二叉链表重新连接起来,同时确保二叉排序树的性质不会丢失。具体分三种情况:
  (1) 如果被删除的结点是叶结点,可以直接删除;
  (2) 如果被删除的结点只有一棵左子树或右子树,需要让该结点的子树成为该结点的父结点的子树,以替代被删除结点的位置;

在这里插入图片描述

  (3) 被删除的结点有左子树和右子树,需要用该结点的直接后继来代替该结点的位置,然后从二叉排序树中删去这个直接后继。

在这里插入图片描述

6. 二叉排序树的查找效率分析

  如果二叉排序树的左、右子树的高度之差的绝对值不超过1,则这样的二叉树称为平衡二叉树,它的平均查找长度为 O ( l o g 2 n ) O(log_2n) O(log2n);如果二叉排序树是一个只有左子树或右子树的单支树(类似于有序的单链表),则它的平均查找长度为 O ( n ) O(n) O(n)
  在等概率情况下,有序列 { 2 , 1 , 4 , 3 } \\{2,1,4,3\\} {2,1,4,3}构成的排序二叉树的查找成功的平均查找长度为
A S L = 1 + 2 × 2 + 3 4 = 2 ASL=\\frac {1+2\\times2+3} {4}=2 ASL=41+2×2+3=2  有序列 { 1 , 2 , 3 , 4 } \\{1,2,3,4\\} {1,2,3,4}构成的排序二叉树的查找成功的平均查找长度为
A S L = 1 + 2 + 3 + 4 4 = 2.5 ASL=\\frac {1+2+3+4} {4}=2.5 ASL=41+2+3+4=2.5  二叉排序树的查找效率主要取决于树的高度,如果要提高查找效率,在构造二叉排序时最好不要使用有序的序列,尽量构造平衡二叉树。

  有关平均查找长度 A S L ASL ASL的知识会在查找这部分再说。

以上是关于数据结构,二叉排序树的主要内容,如果未能解决你的问题,请参考以下文章

二叉树及特殊二叉树(满二叉树完全二叉树二叉排序树平衡二叉树)的定义和性质(附详细推理过程)

树结构实际应用之 二叉排序树

二叉排序树

二叉排序树

数据结构——19 判断是否是二叉排序树

数据结构——19 判断是否是二叉排序树