动态查找树表之二叉排序树

【说明】文章内容来源于课程课件

1.定义:二叉排序树或者是一棵空树;或者是具有如下特性的二叉树:

1)若它的左子树不空,则左子树上所有结点的值均小于根结点的值;

2)若它的右子树不空,则右子树上所有结点的值均大于根结点的值;

3)它的左、右子树也都分别是二叉排序树。

说明:二叉排序树的中序遍历序列是排序好的

2.二叉排序树的查找算法:

若二叉排序树为空,则查找不成功;否则

1)若给定值等于根结点的关键字,则查找成功

2)若给定值小于根结点的关键字,则继续在左子树上进行查找

3)若给定值大于根结点的关键字,则继续在右子树上进行查找

两种查找要求:

1. 查找成功,返回结点指针;查找不成功,返回空指针;

2. 查找成功,返回结点指针;查找不成功,返回查找路径上访问的最后一个结点的指针;(2种算法可用于插入算法

  1种算法:递归实现伪代码:

BiTree SearchBST ( BiTree T, KeyType key)
 { // 返回结点指针或空指针
    if ( ! T || EQ(key, T->data.key)   
     return T;                    // 查找成功或为空
    else if (LT(key, T->data.key) )
      return SearchBST ( T->lchild, key );
                                    // 在左子树中继续查找
    else return SearchBST ( T->rchild, key ); 
                                    // 在右子树中继续查找
} // SearchBST

2种算法:

查找成功则返回指向该数据元素的结点的指针 p 并返回函数值为 TRUE;

查找不成功,则返回指向查找路径上访问的最后一个结点的指针 p ,并返回函数值FALSE,

为此,定义一个指针 f 指向当前访问的结点的双亲,其初始调用值为NULL

Status SearchBST (BiTree T, KeyType key, BiTree f, BiTree &p ) { 
     //p是返回指针,f是T的双亲
   
    if (!T) { p = f;  return FALSE; }     // 查找不成功
    else  if ( EQ(key, T->data.key) ) { p = T;  return TRUE; }// 查找成功
    else  if ( LT(key, T->data.key) ) 
        SearchBST (T->lchild, key, T, p ); // 在左子树中继续查找
    else
        SearchBST (T->rchild, key, T, p ); // 在右子树中继续查找
} // SearchBST

3.插入算法

根据动态查找表的定义,“插入”操作在查找不成功时才进行;

若二叉排序树为空树,则新插入的结点为新的根结点;否则,新插入的结点必为一个新的叶子结点,其插入位置由查找过程得到。

伪代码:

Status Insert BST(BiTree &T, ElemType e ) 
{
  // 当二叉排序树中不存在关键字等于 e.key 的
  // 数据元素时,插入元素值为 e 的结点,并返
  // 回 TRUE; 否则,不进行插入并返回FALSE
   if (!SearchBST ( T, e.key, NULL, p ))
   {    //p为查找路径上访问的最后结点指针
        s =  new  BiTNode;// 为新结点分配空间
        s->data = e;  
        s->lchild = s->rchild = NULL;  
        if  ( !p )  T = s;   // 插入 s 为新的根结点  
        else  if ( LT(e.key, p->data.key) ) 
            p->lchild = s;   //插入 *s 为*p 的左孩子
        else  p->rchild = s; //插入 *s 为*p 的右孩子
        return TRUE;     // 插入成功
   }    
   else return FALSE; //不进行插入并返回FALSE
} // Insert BST

4.删除算法

与插入相反,删除在查找成功之后进行,并且要求在删除二叉排序树上某个结点之后,仍然保持二叉排序树的特性

可分三种情况讨论:

1)被删除的结点是叶子其双亲结点中相应指针域的值改为“空”

2)被删除的结点只有左子树,或者只有右树其双亲结点的相应指针域的值改为 “指向被删除结点的左子树或右子树”。

3)被删除的结点既有左子树,也有右子树以其前驱替代之,然后再删除该前驱结点

其中删除操作过程如下所描述:

void Delete ( BiTree &p ){
   // 从二叉排序树中删除结点 p,
   // 并重接它的左子树或右子树
   if (!p->rchild)  {      
       //右子树空则只需重接它的左子树
        q = p;  
        p = p->lchild;  
        delete(q);
   }           
   else if (!p->lchild) {   
        //左子树为空树则只需重接它的右子树
        q = p; 
        p = p->rchild;  
        delete(q);
    }    
   else {          
        // 左右子树均不空,以其前驱替代之,然后再删除该前驱结点
        q = p;  s = p->lchild;
        while (s->rchild) { q = s;  s = s->rchild; }// s 指向被删结点的前驱,q是s的双亲
        p->data = s->data;               //用s 替代被删除结点p
        if (q!=p)  q->rchild = s->lchild; //修改s双亲指针
        else  p->lchild = s->lchild;// p的前驱就是其左孩子,// 重接*p的左子树
        delete(s);
    }                  
} // Delete

5.查找性能的分析

为了提高查找的效率,也就是减小这个平均查找长度,需要进一步关于二叉平衡树的内容,之后更新~

欢迎批评指正~

1.对于二叉排序树,下面的说法( )是正确的。 A.二叉排序树动态树表查找不成功时插入新结点时,会引起树的重新分裂和组合 B.对二叉排序树进行层序遍历可得到有序序列 C.用逐点插入法构造二叉排序树时,若先后插入的关键字有序,二叉排序树的深度最大 D.在二叉排序树中进行查找,关键字的比较次数不超过结点数的1/2 2.在有n个结点且为完全二叉树的二叉排序树查找一个键值,其平均比较次数的数量级为( )。 A.O(n) B.O(log2n) C.O(n*log2n) D.O(n2) 3.静态查找动态查找的根本区别在于( )。 A. 它们的逻辑结构不一样 B. 施加在其上的操作不同 C. 所包含的数据元素型不一样 D. 存储实现不一样 4.已知一个有序为{12,18,24,35,47,50,62,83,90,115,134},当折半查找值为90的元素时,经过( )次比较后查找成功。 A.2 B.3 C.4 D.5 5.已知数据序列为(34,76,45,18,26,54,92,65),按照依次插入结点的方法生成一棵二叉排序树,则该树的深度为( )。 A. 4 B. 5 C. 6 D. 7 6.设散列长m=14,散列函数H(k)=k mod 11 。中已有15,38,61,84四个元素,如果用线性探测法处理冲突,则元素49的存储地址是( )。 A. 8 B. 3 C. 5 D. 9 7. 平衡二叉树的查找效率呈( )数量级。 A. 常数阶 B. 线性阶 C. 对数阶 D. 平方阶 8. 设输入序列为{20,11,12,…},构造一棵平衡二叉树,当插入值为12的结点时发生了不平衡,则应该进行的平衡旋转是( )。 A. LL B. LR C. RL D. RR 二、填空题(每空3分,共24分)。 1.在有序A[1..18]中,采用二分查找算法查找元素值等于A[7]的元素,所比较过的元素的下标依次为 。 2.利用逐点插入法建立序列(61,75,44,99,77,30,36,45)对应的二叉排序树以后,查找元素36要进行 次元素间的比较,查找序列为 。 3. 用顺序查找法在长度为n的线性中进行查找,在等概率情况下,查找成功的平均比较次数是 。 4. 二分查找算法描述如下: intSearch_Bin(SST ST, KT key) { low=1 ; high=ST. length; while(low<=high) { mid=(low+high)/2; if(key==ST.elem[mid].key) return mid; else if(key<ST.elem[mid].key) ; else ; } return 0; } 5.链式二叉树的定义如下: typedef struct Btn{ TElemType data; ; }BTN ,*BT; 6.在有n个叶子结点的哈夫曼树中,总结点数是 。 三、综合题(共52分)。 1. (共12分)假定关键字输入序列为19,21,47,32,8,23,41,45,40,画出建立二叉平衡树的过程。 2. (共15分)有关键字{13,28,31,15,49,36,22,50,35,18,48,20},Hash 函数为H=key mod 13,冲突解决策略为链地址法,请构造Hash(12分),并计算平均查找长度(3分)。 ASL= 3. (共10分)设关键字码序列{20,35,40,15,30,25},给出平衡二叉树的构造过程。 4. (共15分)设哈希长为m=13,散列函数为H(k)=k mod 11,关键字序列为5,7,16,12,11,21,31,51,17,81;试求:散列后的中关键字分布(假定解决冲突的方法为线性探测再散列法);求平均查找长度ASL;计算该的装填因子。 (1)按要求求哈希(10分): 0 1 2 3 4 5 6 7 8 9 10 11 12 (2)计算ASL(3分): ASL= (3)计算装填因子(2分):装填因子=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值