二叉搜索树

#include <iostream>
using namespace std;

class Node
{
public:
    int key;
    Node* llink;
    Node* rlink;
public:
    explicit Node(int a){key = a; llink = rlink = nullptr;}
};

class SerchTree
{
public:
    Node *root;
public:
    SerchTree();
    SerchTree(int *, int n); //searchTree的构建,通过读取int数组,然后向树中依次插入
                                //完成构建

    Node * serch( int);
    void insert(int);
    void mergeDelete(int a);
    void copyDelete(int a );
    void display(Node*);
};

SerchTree::SerchTree() { root = nullptr;}

Node* SerchTree::serch( int key)
{
    Node* p = root;
    while(p)
    {
        if(p->key > key)
            p = p ->llink;
        else if(p->key < key)
            p = p ->rlink;
        else
            return p;
    }

    return nullptr;
}

void SerchTree::insert(int a)
{
    Node* p = root;
    Node* prep = nullptr;
    while(p)
    {
        if(p->key > a)
        {prep = p; p = p->llink;}
        else
        {prep = p ; p = p ->rlink;}
    }
    if(!root) //这一步是构建树的时候需要的,
        // 在空树的情况下需要自己构建根结点
        root = new Node(a);
    else if(prep && prep->key > a)
        prep->llink = new Node(a);
    else if(prep && prep->key < a)
        prep->rlink = new Node(a);

}

SerchTree::SerchTree(int * a ,int n)
{
    root = nullptr; //根节点初始化
    for(int i = 0; i < n; i++)
    {
        insert(a[i]);
    }
}

//合并删除
//找到被删节点左子树的最右下角的节点,将被删节点的右子树连在此节点的右子树,删除被删节点
//如果被删节点有一个孩子,子承父业
void SerchTree::mergeDelete(int a)
{
    Node* p = root; //当前节点
    Node* prep = nullptr;//当前节点的父节点
    while(p)
    { //找到被删节点以及它的父节点
        if(p->key > a)
        {prep = p; p = p->llink;}
        else if(p->key <a)
        {prep = p; p = p->rlink;}
        else
            break;
    }
    if(!p)
        return;
    //子承父业删除
    if(!p->rlink)
    {
        if(p->key > prep->key)
            prep->rlink = p->llink ;
        else
            prep->llink = p->llink;
        delete(p);
        return;
    }
    else if(!p->llink)
    {
        if(p->key > prep->key)
            prep->rlink = p->rlink ;
        else
            prep->llink = p->rlink;
        delete(p);
        return;
    }
        //合并删除
    else
    {
        Node* temp = p->llink;
        while(temp->rlink) //找到被删节点左子树的最大节点
            temp = temp->rlink;
        temp->rlink = p->rlink;//将被删节点的右子树连在被删节点左子树最大节点的右端

        if (nullptr == prep) { //如果根被删,那么以根的左子树的根节点为根
            root = p->llink;
            delete p;
            return;
        }
        //将被删节点的左子树插在正确位置
        if(prep->key > p->key)
            {prep->llink = p->llink;
            delete p;
            return;}
        else
            {prep->rlink = p->llink;
            delete p;
            return;}
    }

}

//复制删除
//当被删节点只有一个孩子,子承父业
//当被删节点有两个孩子,从左子树找到最大节点或者从右子树找到最小节点,将节点key复制给被删节点,然后删除最大(最小)节点
void SerchTree::copyDelete(int a)
{
    Node* p = root;
    Node* prep = nullptr;

    while(p)
    {
        if(p->key > a)
        {prep = p; p = p->llink; }
        else if(p->key < a)
        {prep = p; p = p->rlink; }
        else
            break;
    }
    if(!p)
        return;
    if(!p->rlink)
    {
        if(p->key > prep->key)
            prep->rlink = p->llink ;
        else
            prep->llink = p->llink;
        delete(p);
    }
    else if(!p->llink)
    {
        if(p->key > prep->key)
            prep->rlink = p->rlink ;
        else
            prep->llink = p->rlink;
        delete(p);
    }    //以上和mergeDelete操作一样
        //下面是复制删除的代码
    else
    {
        Node* temp = p->llink;
        Node* preptemp = p;
        while(temp->rlink)
        {preptemp = temp;
            temp = temp->rlink;}
        p->key = temp->key;
        preptemp->rlink = temp->llink;
        preptemp= nullptr;
        delete(temp);
    }
    return;
}

//通过中序遍历来输出这个SEARCHTREE
void SerchTree::display(Node* root)
{
    if(root)
    {
        display(root->llink);
        cout<<root->key<<" ";
        display(root->rlink);
    }
}

int main()
{
    int a[10] = {2,56,123,65,9,8,7,1,4,513};
    SerchTree atree(a , 10);
    atree.display(atree.root);
    printf("\n");

    atree.insert(5);
    atree.display(atree.root);
    printf("\n");

    atree.mergeDelete(2);
    atree.display(atree.root);
    printf("\n");

    atree.copyDelete(513);
    atree.display(atree.root);
    printf("\n");
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值