【数据结构】二叉搜索树

来源:互联网 发布:诸神黄昏天梭进阶数据 编辑:程序博客网 时间:2024/06/05 16:24

什么是二叉搜索树

二叉搜索树(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}
1 0
原创粉丝点击