二叉搜索树

      之前在学二叉搜索树的相关知识,今天我自己把有讲的没讲的都实现了一遍,的确有点收获~

#include<iostream>
using namespace std;
struct BTreeNode{
    //二叉搜索树
    int data;
    BTreeNode *parent;
    BTreeNode *lchild;
    BTreeNode *rchild;
};
void print(BTreeNode *t){
    //遍历二叉搜索树,输出排序结果
    if(t == NULL)return ;
    print(t->lchild);
    cout<<t->data<<' ';
    print(t->rchild);
}
BTreeNode* Search(BTreeNode *t,int x){
    //返回第一个查找到的元素的位置
    if(t == NULL || t->data == x)return t;
    if(t->data > x)return Search(t->lchild,x);
    return Search(t->rchild,x);
}
BTreeNode* Max(BTreeNode *t){
    //返回该二叉搜索树最大值
    BTreeNode *p = NULL;
    while(t != NULL){
        p = t;
        t = t->rchild;
    }
    return p;
}
BTreeNode* Min(BTreeNode *t){
    //返回该二叉搜索树最小值
    BTreeNode *p = NULL;
    while(t != NULL){
        p = t;
        t = t->lchild;
    }
    return p;
}
BTreeNode* Successor(BTreeNode *n){
    //返回该结点的后继结点(即排序后的后一个结点)
    //存在右子树
    if(n->rchild != NULL)return Min(n->rchild);
    //往上找到第一个比它大的元素,也可能没有
    BTreeNode *p = n->parent;
    while(p != NULL && n != p->lchild){
        n = p;
        p = p->parent;
    }
    return p;
}
BTreeNode* Predecessor(BTreeNode *n){
    //返回该结点的前驱结点(即排序后的前一个元素)
    //存在左子树
    if(n->lchild != NULL)return Max(n->lchild);
    //往上找到第一个比它小的元素,也可能没有
    BTreeNode *p = n->parent;
    while(p != NULL && n != p->rchild){
        n = p;
        p = p->parent;
    }
    return p;
}
void Insert(BTreeNode *&t,int x){
    //插入
    BTreeNode *p = NULL,*root = t;
    while(t != NULL){
        p = t;
        if(t->data >= x)t = t->lchild;
        else t = t->rchild;
    }
    t = new BTreeNode;
    t->data = x;
    t->lchild = t->rchild = NULL;
    if(p == NULL){
        //若树为空
        root = t;
		t->parent = NULL;
	}
    else{
        t->parent = p;
        if(p->data > x)p->lchild = t;
        else p->rchild = t;
    }
    //恢复到函数前状态
    t = root;
}
bool Delete(BTreeNode *t,int x){
    //删除第一个找到的x
    BTreeNode *del = Search(t,x);
    //不存在此元素
    if(del == NULL)return false;
    BTreeNode *sr;
    if(del->lchild != NULL && del->rchild != NULL){
        //若该结点有左右子树,则用其后继的值覆盖它,然后删除它的后继。
        sr = Successor(del);
        del->data = sr->data;
        del = sr;
    }
	BTreeNode *p = del->parent;
	if(p == NULL){
         t = NULL;
         delete del;
         return true;     
    }
	if(del->lchild == NULL && del->rchild == NULL){
        //该结点为叶子结点
        if(del == p->lchild)p->lchild = NULL;
        else p->rchild = NULL;
        delete del;
        return true;
    }
    if(del->lchild == NULL){
        //该结点没有左子树
        if(del == p->lchild)p->lchild = del->rchild;
        else p->rchild = del->rchild;
        del->rchild->parent = p;
        delete del;
        return true;
    }
    if(del->rchild == NULL){
        //该结点没有右子树
        if(del == p->lchild)p->lchild = del->lchild;
        else p->rchild = del->lchild;
        del->lchild->parent = p;
        delete del;
        return true;
    }
    return true;
}
BTreeNode* Create(){
    //创建二叉搜索树,默认输入-1表示输入结束
    BTreeNode* root = NULL;
    int n;
    while(cin>>n && n!=-1)
		Insert(root,n);
    return root;
}
int main(){
    int t;
    BTreeNode *root;
    cin>>t;
    while(t--){
        root = Create();
        print(root);
        cout<<endl;
        int n;
        cin>>n;
        Delete(root,n);
        print(root);
        cout<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值