二叉排序树——完整代码实现

   二叉排序树,又称二叉查找树。它或者是一颗空树,或者是具有下列性质的二叉树。

(1)      若他的左子树不为空,则左子树上所有结点的值均小于他的根结点的值。

(2)      若他的右子树不为空,则右子树上所有结点的值均大于他的根结点的值。

(3)      他的左右子树也分别是二叉排序树。

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef struct BiTNode
{
    int data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
bool SearchBST(BiTree T,int key,BiTree f,BiTree *p)
{
    if(!T)//查找不成功
    {
        *p=f;
        return false;
    }
    else if(key==T->data)//查找成功
    {
        *p=T;
        return true;
    }
    else if(key<T->data)//查找左子树
        return SearchBST(T->lchild,key,T,p);
    else//查找右子树
        return SearchBST(T->rchild,key,T,p);
}
bool InsertBST(BiTree *T,int key)
{
    BiTree p,s;
    if(!SearchBST(*T,key,NULL,&p))
    {
        s=(BiTree)malloc(sizeof(BiTNode));
        s->data=key;
        s->lchild=s->rchild=NULL;
        if(!p)//该树为空树,s为根节点
            *T=s;
        else if(key<p->data)
            p->lchild=s;//s为左孩子
        else
            p->rchild=s;//s为右孩子
        return true;
    }
    return false; //已存在该节点
}
/*从二叉排序树中删除节点p,并重新接上他的左、右子树*/
bool Delete(BiTree *p)
{
    BiTree q,s;
    if((*p)->rchild==NULL)//右子树为空,只需要重接他的左子树
    {
        q=*p;
        *p=(*p)->lchild;
        free(q);
    }
    else if((*p)->lchild==NULL)//左子树为空,只需要重接他的右子树
    {
        q=*p;
        *p=(*p)->rchild;
        free(q);
    }
    else//左右子树均不为空
    {
        q=*p;
        s=(*p)->lchild;
        while(s->rchild)//转左,然后向右走到尽头,找p的前驱。
        {
            q=s;
            s=s->rchild;
        }
        (*p)->data=s->data;//s指向被删结点的直接前驱,然后用s来替换p
        if(q!=*p)//如果p,q指向不同的结点,则表明s结点下面还有右子树。
            q->rchild=s->lchild;//重接q的右子树。
        else
            q->lchild=s->lchild;//重接q的左子树。
        free(s);
    }
    return true;
}
bool DeleteBST(BiTree *T,int key)
{
    if(!*T)//查找不成功
    {
        return false;
    }
    else if(key==(*T)->data)//查找成功
    {
        return Delete(T);
    }
    else if(key<(*T)->data)//查找左子树
        return DeleteBST(&(*T)->lchild,key);
    else//查找右子树
        return DeleteBST(&(*T)->rchild,key);
}
void InOrderTraverse(BiTree T)//中序遍历
{
    if(T==NULL)
        return;
    InOrderTraverse(T->lchild);
    printf("%d ",T->data);
    InOrderTraverse(T->rchild);
}
int main()
{
    int a[]={62,88,58,47,35,73,51,99,37,93};
    BiTree T=NULL;
    for(int i=0;i<10;i++)
        InsertBST(&T,a[i]);
    InOrderTraverse(T);
    cout<<endl;
    cout<<"请输入要插入的数据"<<endl;
    int key;
    cin>>key;
    if(InsertBST(&T,key))
    {
        cout<<"插入成功"<<endl;
        InOrderTraverse(T);
        cout<<endl;
    }
    else
        cout<<"插入失败"<<endl;
    cout<<"请输入要删除的数据"<<endl;
    cin>>key;
    if(DeleteBST(&T,key))
    {
        cout<<"删除成功"<<endl;
        InOrderTraverse(T);
        cout<<endl;
    }
    else
        cout<<"删除失败"<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值