二叉搜索树

什么是二叉搜索树

二叉搜索树(BST)也称为二叉排序树或二叉查找树。

二叉搜索树:一棵二叉树,可以为空;如果不为空,满足以下性质。

  • 非空左子树的键值小于其根结点的键值。
  • 非空右子树的键值大于其根结点的键值。
  • 左右子树都是二叉搜索树。

二叉搜索树的查找操作

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

若树非空,则根结点关键字和X进行比较,并进行处理:

  • 若X小于根结点的值,只需要在左子树中继续搜索。
  • 若X大于根结点的值,在右子树中继续搜索。
  • 若两者比较结果相等,搜索完成,返回指向此结点的指针。

图示

Position Find ( ElementType X, BinTree BST )
{
    if( !BST ) return NULL;//查找失败
    if( X > BST->Data )//如果X大于根结点的值,到右子树中查找
        return Find( X, BST->Right );
    else if ( X < BST->Data )//否则,在左子树中查找
        return Find( X, BST->Left );
    else//如果相等,则查找成功,返回结点的地址
        return BST;
}

上述代码是用尾递归(在程序分支的最后进行递归),效率不高。从编译的角度讲,尾递归都是可以用循环来实现的。所以,可将尾递归改为迭代函数。

Position IterFind( ElementType X, BinTree BST )
{
    while( BST ){
        if( X > BST->Data )
            BST=BST->Right;
        else if ( X < BST-> Data )
            BST=BST->Left;
        else
            return BST;
    }
    return NULL;
}

查找最大和最小值

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

图示

//查找最小值的递归算法
Position FindMin( BinTree BST )
{
    if( !BST ) return NULL;//空的二叉树返回NULL
    if( !BST->Left ){//找到最左结点并返回
        return  BST;
    }else{//如果存在左孩子就继续查找
        return FindMin( BST->Left );
    }
}

//查找最大值的迭代算法
Position FindMax( BinTree BST )
{
    if( BST )//一直向右查找
        while( BST->Right ) BST = BST->Right;
    return BST;
}

二叉搜索树的插入

图示

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;
    }
}

二叉搜索树的删除

有三种情况

  1. 要删除的是叶结点:直接删除,并修改其父结点指针—置为NULL
  2. 要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点。
  3. 要删除的结点有左、右两棵子树:用另一结点替代被删除的结点:右子树的最小元素,或者左子树的最大元素。
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
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章