数据结构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;
}
相关推荐
一条大祥脚23 分钟前
26.1.9 轮廓线dp 状压最短路 构造
数据结构·c++·算法
cpp_25012 小时前
P2708 硬币翻转
数据结构·c++·算法·题解·洛谷
程序猿阿伟3 小时前
《Python复杂结构静态分析秘籍:递归类型注解的深度实践指南》
java·数据结构·算法
UIUI4 小时前
list_for_each_entry
linux·数据结构·链表
豆沙沙包?6 小时前
2026年--Lc334-2130. 链表最大孪生和(链表转数组)--java版
java·数据结构·链表
Python_Study20258 小时前
制造业数据采集系统选型指南:从技术挑战到架构实践
大数据·网络·数据结构·人工智能·架构
SmoothSailingT9 小时前
408每日一题——数据结构
数据结构·考研·408
im_AMBER11 小时前
Leetcode 99 删除排序链表中的重复元素 | 合并两个链表
数据结构·笔记·学习·算法·leetcode·链表
s砚山s12 小时前
代码随想录刷题——二叉树篇(十三)
数据结构·算法
ulias21212 小时前
AVL树的实现
开发语言·数据结构·c++·windows