数据结构04——二叉树搜索树BST

数据结构二叉搜索树BST

静态查找&动态查找

静态查找(Static Search)

指:在查找过程中,查找表的内容是固定不变的,不允许插入或删除记录,只进行查找(find)操作。

关键特征:查找表在构建完成后不再发生结构变化

只支持:查找(Search)

不支持:插入(Insert)& 删除(Delete)

动态查找(Dynamic Search)

指:在查找过程中,查找表允许进行插入和删除操作,表的结构可能随操作而发生变化。

关键特征:查找表是可变的

支持:查找(Search)、插入(Insert)、删除(Delete)

需要维护结构性质(如平衡性)

二叉搜索树(BST,Binary Search Tree),也称 二叉排序树 或 二叉查找树。

复制代码
二叉搜索树是一棵二叉树,可以为空;
如果不为空,满足以下性质:
非空左子树的所有键值小于其根结点的键值。
非空右子树的所有键值大于其根结点的键值。
左、右子树都是二叉搜索树。

补充说明

BST 的关键在于:左小右大,递归成立

对 BST 进行 中序遍历,得到的是一个递增有序序列

Find查找结点

二叉搜索树的查找操作:Find

查找从根结点开始,如果树为空,返回 NULL。

若搜索树非空,则将根结点关键字与 X 进行比较,并进行不同处理:

① 若 X 小于根结点关键值,只需在左子树中继续搜索;

② 如果 X 大于根结点的关键值,在右子树中进行继续搜索;

③ 若两者比较结果相等,搜索完成,返回指向此结点的指针。

递归法

c 复制代码
Position Find( ElementType X, BinTree BST )
{
    if ( !BST )
        return NULL;                 /* 查找失败 */

    if ( X > BST->Data )
        return Find( X, BST->Right );/* 在右子树中继续查找 */
    else if ( X < BST->Data )
        return Find( X, BST->Left ); /* 在左子树中继续查找 */
    else                             /* X == BST->Data */
        return BST;                  /* 查找成功,返回找到结点的地址 */
}

非递归法

由于非递归函数的执行效率高,可将"尾递归"函数改为迭代函数

实际工程与考试中,迭代版(非递归法)更高效、更常用

c 复制代码
Position IterFind( ElementType X, BinTree BST )
{
    while ( BST ) {
        if ( X > BST->Data )
            BST = BST->Right;   /* 向右子树中移动,继续查找 */
        else if ( X < BST->Data )
            BST = BST->Left;    /* 向左子树中移动,继续查找 */
        else                    /* X == BST->Data */
            return BST;         /* 查找成功,返回找到结点的地址 */
    }
    return NULL;                /* 查找失败 */
}

Find查找的效率取决于树的高度,所以我们希望这个树尽量的平衡,不要出现一边倒。

查找最大&最小结点

最大元素一定在树的最右分支的端结点上
最小元素一定在树的最左分支的端结点上

查找最小元素的递归函数

c 复制代码
Position FindMin( BinTree BST )
{
    if ( !BST )
        return NULL;            /* 空的二叉搜索树,返回 NULL */
    else if ( !BST->Left )
        return BST;             /* 找到最左叶结点并返回 */
    else
        return FindMin( BST->Left );   /* 沿左分支继续查找 */
}

查找最大元素的迭代函数

c 复制代码
Position FindMax( BinTree BST )
{
    if ( BST )
        while ( BST->Right )
            BST = BST->Right;   /* 沿右分支继续查找,直到最右叶结点 */

    return BST;
}

二叉搜索树的插入

同一组元素,如果插入顺序不同,二叉搜索树的形态可以完全不同。

所以,这也是我们下列函数能成立的原因

c 复制代码
BinTree Insert( ElementType X, BinTree BST )
{
    if( !BST ){
        /* 若原树为空,生成并返回一个结点的二叉搜索树 */
        BST = malloc(sizeof(struct TreeNode));
        BST->Data = X;
        BST->Left = BST->Right = NULL;
    }
    else    /* 开始找要插入元素的位置 */
        if( X < BST->Data )
            BST->Left = Insert( X, BST->Left );
            /* 递归插入左子树 */
        else if( X > BST->Data )
            BST->Right = Insert( X, BST->Right );
            /* 递归插入右子树 */
        /* else X已经存在,什么都不做 */

    return BST;
}

二叉搜索树的删除

有三种情况

第一种,删除叶子结点 :直接删除,并修改其父结点指针------为NULL

第二种,删除的结点只有一个孩子结点:将其父结点的指针指向被删除结点的孩子结点

例:删除33,41的指针指向35

第三种,删除的结点有左、右两颗子树:用另一个结点代替被删除的结点,右子树的最小元素或者左子树的最大元素

例:删除41

代码

c 复制代码
BinTree Delete( ElementType X, BinTree BST )
{
    Position Tmp;

    if( !BST )
        printf("要删除的元素未找到");
    else if( X < BST->Data )
        BST->Left = Delete( X, BST->Left );     /* 左子树递归删除 */
    else if( X > BST->Data )
        BST->Right = Delete( X, BST->Right );   /* 右子树递归删除 */
    else {  /* 找到要删除的结点 */
        if( BST->Left && BST->Right ) {          /* 被删除结点有左右两个子结点 */
            Tmp = FindMin( BST->Right );          /* 在右子树中找最小的元素填充删除结点 */
            BST->Data = Tmp->Data;
            BST->Right = Delete( BST->Data, BST->Right );
                                                  /* 在删除结点的右子树中删除最小元素 */
        }
        else {  /* 被删除结点有一个或无子结点 */
            Tmp = BST;
            if( !BST->Left )                      /* 有右孩子或无子结点 */
                BST = BST->Right;
            else if( !BST->Right )                /* 有左孩子或无子结点 */
                BST = BST->Left;
            free( Tmp );
        }
    }

    return BST;
}
相关推荐
仰泳的熊猫2 小时前
1077 Kuchiguse
数据结构·c++·算法·pat考试
阿里巴巴AI编程社区2 小时前
Qoder 提效实战:数据开发工程师用 Qoder 提效50%
数据结构
消失的旧时光-19432 小时前
从 C 链表到 Android Looper:MessageQueue 的底层原理一条线讲透
android·数据结构·链表
夏乌_Wx3 小时前
练题100天——DAY28:找消失的数字+分发饼干
数据结构·算法
lzh200409193 小时前
二叉搜索树与双向链表
数据结构·链表
WolfGang0073213 小时前
代码随想录算法训练营Day48 | 108.冗余连接、109.冗余连接II
数据结构·c++·算法
45288655上山打老虎4 小时前
List容器
数据结构·windows·list
NeDon5 小时前
[OJ]数据结构:移除链表元素
c语言·数据结构·算法·链表
承渊政道5 小时前
一文彻底搞清楚链表算法实战大揭秘和双向链表实现
c语言·数据结构·算法·leetcode·链表·visual studio