二叉排序树

二叉排序树 (BST) :

建立在二叉树基础上,性质如下

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结构的值
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结构的值
  • 它的左子树和右子树都是二叉排序树
  • 故左子树所有结点一定比父结点小,右子树所有结点一定比父结点大 
查找,近乎析半查找,输出采用中序遍历,可获取从大到小序列
构造一颗二叉排序树的目的,其实并不是为了排序,而是为了提高查找和插入删除关键字的速度。

代码示例:
创建:输入前序排列的数组
PNODE creatree(PNODE *tr,int a[])
{
    //cout<<
     
     
      
      inode=c;
            n++;
            creatree(&(*tr)->left,a);
            n++;
            creatree(&(*tr)->right,a);
        }
}
     
     

插入:
int inserttr(PNODE *tr,int a)//注意形参为指针的指针,若PNODE tr的话无法传回tre
{
    if(*tr==NULL)
    {
        *tr=new NODE;
        (*tr)->inode=a;//(*tr)加括号
        (*tr)->left=NULL;
        (*tr)->right=NULL;
    }
    else{
        if((*tr)->inode>a)
        {
            inserttr(&(*tr)->left,a);
        }
        else if((*tr)->inode
     
     
      
      right,a);
        }
    }
    return 1;
}
     
     
该节点若是空,插入即可,
非空,小于该节点值,再插入左子树,否则,插入右子树,等于该节点值,则不执行;并不会引起二叉树其他部分的结构变化
查找:
PNODE* findq(PNODE *tr,int a)//查找不成功返回-1;其他返回1;
{
    if((*tr)==NULL)
       {
        return NULL;
       }
    else if((*tr)->inode==a)
        return tr;
    else
    {
        if((*tr)->inode>a)
        {
            return findq(&(*tr)->left,a);//层层返回消息
        }
        else
        {
            return findq(&(*tr)->right,a);
        }
    }

}
该节点若是空,返回,
非空,小于该节点值,入左子树查找,大于该节点,入右子树查找,等于该节点,即找到

删除:代码块一直显示empty,不知为啥,只有直接贴出来了;此代码验证无误,有许多博客写的不全面或是错的
int deletetr(PNODE *tr,int a)
{
    PNODE *c=(findq(tr,a));
    PNODE s,q;
    if(c==NULL)
        return NULL;
    if(((*c)->left!=NULL)&&((*c)->right!=NULL))//被删除节点有左右子树
    {
        q=*c;
        s=(*c)->left;
        while((s)->right)//寻找左子树最右节点
        {
            q=s;
            s=(s)->right;
        }
        (*c)->inode=(s)->inode;//交换被删除节点与最右节点的值,子树指针保留,这样操作比较方便
        //最右节点可能存在左子树,将其保留,但注意:
        if(q==(*c))//此时,新节点就是被删除节点的左子树根
            q->left=s->left;
        else
            q->right=s->left;
        delete s;

    }
    else if(((*c)->left==NULL)&&((*c)->right==NULL))
    {
        q=*c;
        (*c)=NULL;
        delete q;
    }
    else
    {
        if((*c)->left!=NULL)
        {
            q=*c;
            (*c)=(*c)->left;
            delete q;
        }
        else
        {
            q=*c;
            (*c)=(*c)->right;
            delete q;
        }
    }
    return 1;
}




叶子节点直接删除;
有一个子树上移连接即可;
两个子树,两种方法
1.用被删结点左子树最右下的结点的值代替被删结点的值,然后删去最右下的结点,即直接前驱
2.用被删结点右子树最左下的结点的值代替被删结点的值,然后删去最左下的结点,即直接后继
为啥可以这样?直接前驱或者直接后继,就是数值上最贴近被替换节点的值,故直接替换值即可,被替换节点的左右子树指针不变,注意指针操作
我们采用方法1
主函数:中序遍历函数参见二叉树内容
typedef struct node{
    int inode;
    node *left;
    node *right;

}NODE ,*PNODE;
int main()
{   int a[7]={12,10,'%','%',19,'%','%'};
    PNODE tre;
    creatree(&tre,a);//前序排列初始化一个树;%表示无节点
    midout(tre);//
    cout<
      
       
    

结果:





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值