二叉搜索树

什么是二叉搜索树

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

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

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

二叉搜索树的查找操作

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

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

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

图示


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

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


   
   
  1. Position IterFind( ElementType X, BinTree BST )
  2. {
  3. while( BST ){
  4. if( X > BST->Data )
  5. BST=BST->Right;
  6. else if ( X < BST-> Data )
  7. BST=BST->Left;
  8. else
  9. return BST;
  10. }
  11. return NULL;
  12. }

查找最大和最小值

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

图示


   
   
  1. //查找最小值的递归算法
  2. Position FindMin( BinTree BST )
  3. {
  4. if( !BST ) return NULL; //空的二叉树返回NULL
  5. if( !BST->Left ){ //找到最左结点并返回
  6. return BST;
  7. } else{ //如果存在左孩子就继续查找
  8. return FindMin( BST->Left );
  9. }
  10. }
  11. //查找最大值的迭代算法
  12. Position FindMax( BinTree BST )
  13. {
  14. if( BST ) //一直向右查找
  15. while( BST->Right ) BST = BST->Right;
  16. return BST;
  17. }

二叉搜索树的插入

图示


   
   
  1. BinTree Insert( ElementType X, BinTree BST )
  2. {
  3. if( !BST ){
  4. //若原树为空,则生成并返回一个节点的二叉树
  5. BST = malloc(sizeof( struct TreeNode));
  6. BST->Data=X;
  7. BST->Left=BST->Right=NUll;
  8. } else{ //开始找插入元素的位置
  9. if( X<BST->Data ) //递归插入到左子树
  10. BST->Left = Insert( X,BST->Left );
  11. else if( X>BST->Data ) //递归插入到右子树
  12. BST->Right = Insert( X,BST->Right );
  13. //else x存在,什么也不做
  14. return BST;
  15. }
  16. }

二叉搜索树的删除

有三种情况

  1. 要删除的是叶结点:直接删除,并修改其父结点指针—置为NULL
  2. 要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点。
  3. 要删除的结点有左、右两棵子树:用另一结点替代被删除的结点:右子树的最小元素,或者左子树的最大元素。

   
   
  1. BinTree Delete( ElementType X, BinTree BST )
  2. {
  3. Position Tmp;
  4. if( !BST ) printf( "要删除的元素未找到");
  5. else if( X < BST->Data ) //如果小于根结点元素,左子树递归
  6. BST->Left = Delete( X, BST->Left );
  7. else if( X > BST->Data ) //大于根结点元素,右子树递归
  8. BST->Right = Delete( X, BST->Right );
  9. else{ /*找到了要删除的结点*/
  10. if( BST->Left && BST->Right){ //被删除的结点有左右两个子结点
  11. Tmp = FindMin( BST->Right ); //在右子树中找到最小的元素替换要删除的结点
  12. BST->Data = Tmp->Data;
  13. BST->Right = Delete( BST->Data, BST->Right ); //删除右子树中那个最小的元素
  14. } else { //被删除的结点有一个或无子结点
  15. Tmp = BST;
  16. if( !BST->Left ); //有右孩子,或无子结点
  17. BST = BST->Right;
  18. else if( !BST->Right ) //有左孩子或无子结点
  19. BST = BST->Left;
  20. free( Tmp );
  21. }
  22. }
  23. return BST
  24. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值