zoukankan      html  css  js  c++  java
  • 二叉搜索树

    查找问题:

    • 静态查找与动态查找
    • 针对动态查找,数据如何组织?

    二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树

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

    1.非空左子树的所有键值小于其根结点的键值。

    2.非空右子树的所有键值大于其根结点的键值。

    3.左、右子树都是二叉搜索树。

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

    Position Find(ElementType X, BinTree BST):从二叉搜索树BST中查找元素X,返回其所在结点的地址

    Position FindMin(BinTree BST):从二叉搜索树BST中查找并返回最小元素所在的结点的地址

    Position FindMax(BinTree BST):从二叉搜索树BST中查找并返回最大元素所在的结点的地址

    BinTree Insert(ElementType X, BinTree BST)

    BinTree Delete(ElementType X, BinTree BST)

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

    • 查找从根结点开始,如果树为空,返回NULL
    • 若搜索树非空,则根结点关键字和X进行比较,并进行不同处理:
    1. 若X小于根结点键值,只需在左子树中继续搜索;
    2. 若果X大于根结点的键值,在右子树中进行继续搜索;
    3. 若两者比较结果是相等,搜索完成,返回指向此结点的指针
     1 Position Find(ElementType X, BinTree BST)
     2 {
     3     if(!BST) return NULL;               /* 查找失败 */
     4     if(X > BST->Data)
     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 Position FindMin(BinTree BST)
     2 {
     3     if(!BST) return NULL;
     4     else if(!BST->Left)
     5         return BST;
     6     else
     7         return FindMin(BST->Left);
     8 }
     9 
    10 Position FindMax(BinTree BST)
    11 {
    12     if(!BST) return NULL;
    13     else if(!BST->Right)
    14         return BST;
    15     else 
    16         return FindMax(BST->Right);
    17 }
    18 
    19 Position FindMin(BinTree BST)
    20 {
    21     if(BST)
    22         while(BST->Left) BST = BST->Left;
    23     return BST;
    24 }
    25 
    26 Position FindMax(BinTree BST)
    27 {
    28     if(BST)
    29         while(BST->Right) BST = BST->Right;
    30     return BST;
    31 }

    二叉搜索树的插入

    分析:关键是要找到元素应该插入的位置,可以采用与Find类似的方法。

     1 BinTree Insert(ElementType X, BinTree BST)
     2 {
     3     if(!BST) {
     4         BST = (BinTree)malloc(sizeof(struct TreeNode));
     5         BST->Data = X;
     6         BSt->Left = BST->Right = NULL;
     7     } else {
     8         if(X < BST->Data)
     9             BST->Left = Insert(X, BST->Left);
    10         else if(X > BST->Data)
    11             BST->Right = Insert(X, BST->Right);
    12     }
    13     return BST;
    14 }

    二叉搜索树的删除

    考虑三种情况:

    • 要删除的是叶节点:直接删除,并再修改其父结点指针--置为NULL
    • 要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点
    • 要删除的结点有左、右两颗子树:用另一结点替代被删除结点:右子树的最小元素或者左子树的最大元素
    1. 取右子树中的最小元素替代
    2. 取左子树中的最大元素替代
     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     return BST;
    23 }
    无欲速,无见小利。欲速,则不达;见小利,则大事不成。
  • 相关阅读:
    知识经济中的贫富差距固定化
    分布式锁
    Activiti
    一种避免在scrollViewDidEndDragging中改变contentInset时闪动的解决方案
    一个封装好的iOS无限滚动组件HXInfiniteScrollView
    使用ReactiveCocoa限制UITextField只能输入正确的金额
    关于ReactiveCocoa的RACObserve的一些研究
    iOS使用masonry快速将一组view在superview中等宽排列
    使用AutoLayOut为UIScrollView添加约束图解及要点
    使用AutoLayOut技术告别UITableViewCell高度计算
  • 原文地址:https://www.cnblogs.com/ch122633/p/8763222.html
Copyright © 2011-2022 走看看