数据结构4-1:二叉搜索树

什么是二叉搜索树?

静态查找就是我们要找的元素是不动的。也就是说在一个集合上主要做的是find操作,而没有delete一个映射的这种操作发生。静态查找我们讲过的一个例子:二分查找就很nice

另外一种查找就是我们要找的这个对象的集合呢本身会动态的发生变化,也就是说经常要发生插入删除,除了查找之外还有插入删除操作发生。

二叉搜索树操作的特别函数:

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

对于尾递归这种操作的执行效率并不高,而且都可以使用循环的方式进行查询。

查找最大和最小元素:FindMin、FindMax

上面这种递归可以换成while循环的方式,效率更佳。

二叉搜索树的插入:Insert

二叉搜索树树的插入要保证插入之后的树仍然是二叉搜索树。

思路:
从根节点开始,如果根节点为空,那么说明这个树是空的,此时开辟一个空间,并赋值即可。

如果树不为空,那就通过递归的方式不断查找每一个节点,比节点数大的看其右子树,比节点数小的看其左子树,递归到最后一个节点后,其左右子树都为空,此时就通过开辟空间直接插入在这最后一个节点上,实现插入操作。

注意:上面的插入是按照字典顺序进行插入的,按照英文顺序排列的。A<B<C<D<E<F<G<……

说明:
一月 Jan. January
二月 Feb. February
三月 Mar. March
四月 Apr. April
五月 May. May
六月 Jun. June
七月 Jul. July
八月 Aug. August
九月 Sept. September
十月 Oct. October
十一月 Nov. November
十二月 Dec. December

二叉搜索树的删除:Delete

删除的如果是叶子节点,直接删除,将该叶子节点的父节点的左指针/或右指针设为NULL。

删除的如果是有一个孩子节点的节点,那么将父节点的指针不再指向这个要删除的节点,而是指向要删除的节点的孩子节点即可。

删除的如果是该节点有左右孩子,那么有两种删除方式:
1、取要删除的节点的右子树中最小的元素,并将该元素替换要删除的节点。
2、取要删除的节点的左子树中最大的元素,并将该元素替换要删除的节点。

习题练习:

讨论:搜索树比较序列的判别

代码:

代码:

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

BinTree Delete( BinTree BST, ElementType X ) 
{ 
    Position Tmp; 

    if( !BST ) 
        printf("要删除的元素未找到"); 
    else {
        if( X < BST->Data ) 
            BST->Left = Delete( BST->Left, X );   /* 从左子树递归删除 */
        else if( X > BST->Data ) 
            BST->Right = Delete( BST->Right, X ); /* 从右子树递归删除 */
        else { /* BST就是要删除的结点 */
            /* 如果被删除结点有左右两个子结点 */ 
            if( BST->Left && BST->Right ) {
                /* 从右子树中找最小的元素填充删除结点 */
                Tmp = FindMin( BST->Right );
                BST->Data = Tmp->Data;
                /* 从右子树中删除最小元素 */
                BST->Right = Delete( BST->Right, BST->Data );
            }
            else { /* 被删除结点有一个或无子结点 */
                Tmp = BST; 
                if( !BST->Left )       /* 只有右孩子或无子结点 */
                    BST = BST->Right; 
                else                   /* 只有左孩子 */
                    BST = BST->Left;
                free( Tmp );
            }
        }
    }
    return BST;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱睡觉的小馨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值