数据结构与算法 第09部分:二叉搜索树

1:二叉排序树结点定义

#define ENDFLAG -1
typedef int ElemType;

typedef struct BSTNode{
	ElemType data;	//结点数据域
	BSTNode *lchild,*rchild;	//左右孩子指针
}BSTNode,*BSTree;

2:二叉排序树的递归查找

BSTree SearchBST(BSTree T,ElemType key)//二叉排序树的递归查找
{
    //若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
	if ((nullptr == T) || key == T->data)
	{
		return T;
	}
       
	if (key < T->data)
	{
		return SearchBST(T->lchild, key);//在左子树中继续查找
	}
	else
	{
		return SearchBST(T->rchild, key); //在右子树中继续查找
	}       
}

3:二叉排序树的插入

void InsertBST(BSTree &T,ElemType e)//二叉排序树的插入
{
    //当二叉排序树T中不存在关键字等于e的数据元素时,则插入该元素
    if(nullptr == T)
    {
        BSTree S = new BSTNode; //生成新结点
        S->data = e;             //新结点S的数据域置为e
        S->lchild = S->rchild = NULL;//新结点S作为叶子结点
        T = S;            		//把新结点S链接到已找到的插入位置
		return;
    }

	if (e < T->data)
	{
		InsertBST(T->lchild, e);//插入左子树
	}
	else if (e > T->data)
	{
		InsertBST(T->rchild, e);//插入右子树
	}          
}

4:二叉排序树的创建

void CreateBST(BSTree &T )//二叉排序树的创建
{
    //依次读入一个关键字为key的结点,将此结点插入二叉排序树T中
    T = nullptr;
    ElemType e;
    cin >> e;
    while(e != ENDFLAG)//ENDFLAG为自定义常量,作为输入结束标志
    {
        InsertBST(T,e);  //插入二叉排序树T中
        cin>>e;
    }
}

5:二叉排序树T中删除关键字等于key的结点

void DeleteBST(BSTree &T,char key)
{
  //从二叉排序树T中删除关键字等于key的结点
    if (nullptr == T)
    {
        return; //树为空则返回
    }

    BSTree p = T; BSTree f = nullptr;
    while(nullptr != p)//查找
    {
        if(p->data == key) break;  //找到关键字等于key的结点p,结束循环
        f = p;                //f为p的双亲
        if (p->data > key)
        {
            p = p->lchild; //在p的左子树中继续查找
        }           
        else
        {
            p = p->rchild; //在p的右子树中继续查找
        }         
    }
    if (nullptr == p)//找不到被删结点则返回
    {
        return;
    }
    BSTree q = p;
    //三种情况:p左右子树均不空、无右子树、无左子树
    if((nullptr != p->lchild)&&(nullptr != p->rchild))//被删结点p左右子树均不空
    {		
        BSTree s = p->lchild;
        while(nullptr != s->rchild)//在p的左子树中继续查找其前驱结点,即最右下结点
        {
            q = s;
            s = s->rchild;
        }
        p->data = s->data;  //s的值赋值给被删结点p,然后删除s结点
        if (q != p)
        {
            q->rchild = s->lchild; //重接q的右子树
        }
        else
        {
            q->lchild = s->lchild; //重接q的左子树
        } 
        delete s;
    }
    else
    {
        if(nullptr == p->rchild)//被删结点p无右子树,只需重接其左子树
        {
            p = p->lchild;
        }
        else if(nullptr == p->lchild)//被删结点p无左子树,只需重接其右子树
        {
             p = p->rchild;
        }
        /*――――――――――将p所指的子树挂接到其双亲结点f相应的位置――――――――*/
        if (nullptr == f)
        {
            T = p;  //被删结点为根结点
        }  
        else if (q == f->lchild)
        {
            f->lchild = p; //挂接到f的左子树位置
        }
        else
        {
            f->rchild = p;//挂接到f的右子树位置
        }
        delete q;
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
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
发出的红包

打赏作者

程序员的资料库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值