数据结构学习笔记4-二叉树搜索树

二叉树搜索树具有较高的搜索效率,并能支持插入和删除运算

性质:1.若左子树不空,则左子树上所有节点的关键字值均小于根节点的关键字值

            2.若右子树不空,则右子树上所有节点的关键字值均大于根节点的关键字值

            3.左右子树也分别是二叉搜索树

实现代码如下:

/**
*   二叉搜索树
*/

#include <iostream>

using namespace std;

class TreeNode
{
private:
    int element;
    TreeNode *lchild,*rchild;
    friend class BSTree;
};

class BSTree
{
private:
    TreeNode *root;
public:
    BSTree(int x);                      //创建二叉搜索树
    ~BSTree();
    void Clear(TreeNode*);
    bool InsertTree(int x);             //插入元素到二叉搜索树
    TreeNode* GetRoot(){return root;}   //获取二叉搜索树的根节点
    TreeNode* SearchTree(int x);
    bool DeleteTree(int x);             //删除元素x
    void PreOrder();         //先序遍历二叉树
    void PreOrder(TreeNode*);
    void InOrder();          //中序遍历二叉树
    void InOrder(TreeNode*);
    void BackOrder();        //后序遍历二叉树
    void BackOrder(TreeNode*);
};

BSTree::BSTree(int x)
{
    root=new TreeNode;
    root->element=x;
    root->lchild=NULL;
    root->rchild=NULL;
}

BSTree::~BSTree()
{
    TreeNode *r=root;
    Clear(r);
}

void BSTree::Clear(TreeNode *r)
{
    if(r)
    {
        Clear(r->lchild);
        Clear(r->rchild);
        delete r;
    }
}

bool BSTree::InsertTree(int x)
{
    TreeNode *p=root,*q=NULL;
    while(p)
    {
        q=p;
        if(x<p->element)
        {
            p=p->lchild;
        }
        else if(x>p->element)
        {
            p=p->rchild;
        }
        else
        {
            cout<<"插入数据重复"<<endl;
            return false;
        }
    }
    p=new TreeNode;
    p->element=x;
    p->lchild=NULL;
    p->rchild=NULL;
    if(p->element<q->element)
    {
        q->lchild=p;
    }
    else if(p->element>q->element)
    {
        q->rchild=p;
    }
    else
    {
        cout<<"插入数据重复"<<endl;
        return false;
    }
    return true;
}

void BSTree::PreOrder()
{
    TreeNode *r=this->root;
    PreOrder(r);
}

void BSTree::PreOrder(TreeNode *r)
{
    if(r)
    {
        cout<<r->element<<'\t';
        PreOrder(r->lchild);
        PreOrder(r->rchild);
    }
}

void BSTree::InOrder()
{
    TreeNode *r=this->root;
    InOrder(r);
}

void BSTree::InOrder(TreeNode *r)
{
    if(r)
    {
        InOrder(r->lchild);
        cout<<r->element<<'\t';
        InOrder(r->rchild);
    }
}

void BSTree::BackOrder()
{
    TreeNode *r=this->root;
    BackOrder(r);
}

void BSTree::BackOrder(TreeNode *r)
{
    if(r)
    {
        BackOrder(r->lchild);
        BackOrder(r->rchild);
        cout<<r->element<<'\t';
    }
}

TreeNode* BSTree::SearchTree(int x)
{
    TreeNode *p=root;
    while(p)
    {
        if(p->element==x)
        {
            cout<<"我们找到了"<<x<<endl;
            return p;
        }
        else if(x<p->element)
        {
            p=p->lchild;
        }
        else
        {
            p=p->rchild;
        }
    }
    cout<<"我们没有找到"<<x<<endl;
}

bool BSTree::DeleteTree(int x)
{
    TreeNode *p=root;
    TreeNode *s=NULL,*r=NULL,*q=NULL,*c=NULL;
    while(p&&p->element!=x)
    {
        q=p;
        if(x<p->element)
            p=p->lchild;
        else
            p=p->rchild;
    }
    if(p->lchild&&p->rchild)    //p节点有两个非空子树
    {
        //寻找p的中序遍历下的直接后继
        s=p->rchild;
        r=p;
        while(s->lchild)
        {
            r=s;
            s=s->lchild;
        }
        p->element=s->element;
        p=s;
        q=r;
    }
    if(!p)
        return false;
    if(p->lchild)
    {
        c=p->lchild;
    }
    else
    {
        c=p->rchild;
    }
    if(p==root)
        root=c;
    else if(p==q->lchild)
    {
        q->lchild=c;
    }
    else
    {
        q->rchild=c;
    }
    delete p;
    return true;
}

int main()
{
    BSTree a(28);
    a.InsertTree(21);
    a.InsertTree(36);
    a.InsertTree(25);
    a.InsertTree(33);

    a.PreOrder();
    cout<<endl;
    a.InOrder();
    cout<<endl;
    a.BackOrder();
    cout<<endl;
    a.DeleteTree(36);
    a.PreOrder();
    return 0;
}

【欢迎读者交流批评指正~】

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值