二叉搜索树

查找问题:

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

二叉搜索树(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 }

 

posted @ 2018-04-09 21:50  习惯就好233  阅读(157)  评论(0编辑  收藏  举报