二叉查找树

二叉查找树的查找、插入(建立在查找的基础上)较简单。

但删除节点需要花点心思,首先是分三种情况:

一、待删节点无左右孩子

二、待删节点只有一个孩子

三、待删节点两个孩子都有

        而第三种情况又存在多种方法:

        1、具体参考《数据结构》(C语言版)严蔚敏 230页,由于不符合本人习惯,略。

        2、查找到节点的直接前驱,用前驱数据替换待删节点数据,然后删除前驱节点。

        3、查找到节点的直接后继,用后继数据替换待删节点数据,然后删除后继节点。

        所以这里又需要一个寻找前驱(后继)的方法,具体就是向左拐然后一直往右(或向右拐一直往左)。


代码如下:

为了符合自己的思维习惯,有些地方比较繁琐(比如判断节点是其父节点的左孩子还是右孩子)。

另外为了验证方便,多写了一个按层次遍历二叉树的方法。


#include <iostream>
#include <vector>
#include <queue>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::queue;

class Node
{
public:
    int data;
    Node *parent;
    Node *lchild;
    Node *rchild;

    Node();
    Node(int value);
};

Node::Node() : data(0), parent(NULL), lchild(NULL), rchild(NULL){}

Node::Node(int value) : data(value), parent(NULL), lchild(NULL), rchild(NULL){}


class CBST
{
private:
    Node *T;

    Node *Predecessor(Node *p); //返回某节点的前驱节点

public:
    CBST(vector<int> src);
    ~CBST();

    bool Search(int value, Node *tree, Node *&p);
    void Insert(int value);
    void Delete(int value);

    void HierarchyShow();     //层序遍历展示
};

CBST::CBST(vector<int> src) : T(NULL)
{
    vector<int>::iterator iter;
    for(iter = src.begin(); iter != src.end(); ++iter)
    {
        Insert(*iter);
    }
}

//若查找成功返回true,p指向所查找节点
//若失败返回false,p指向最后访问的节点
bool CBST::Search(int value, Node *tree, Node *&p)
{
    if (NULL == tree)
    {
        return false;
    }
    else
    {
        p = tree;

        if (tree->data < value)
        {       
            Search(value, tree->rchild, p);
        }
        else if (tree->data > value)
        {
            Search(value, tree->lchild, p);
        }
        else    //equal, found
        {
            return true;
        }
    }
}

void CBST::Insert(int value)
{
    if (!T)
    {
        Node *q = new Node(value);
        T = q;
    }
    else
    {
        Node *p = NULL;
        if (!Search(value, T, p))
        {
            Node *q = new Node(value);
            q->parent = p;

            if (p->data < value)
            {    
                p->rchild = q;
            }
            else    //p->data > value
            {
                p->lchild = q;
            }
        }
        else
        {
            cout<<"element already exist, insertion failed"<<endl;
        }
    }  
}

//当待删节点左右孩子均不为空时,采用用直接前驱替换,删直接前驱节点的方法
void CBST::Delete(int value)
{
    Node *p = NULL;
    if (Search(value, T, p))
    {
        if ((NULL == p->lchild) && (NULL == p->rchild))
        {
            if (p->parent->lchild == p) p->parent->lchild = NULL;
            else p->parent->rchild = NULL;
            delete p;
            p = NULL;
        }
        else if (NULL == p->lchild)
        {
            Node *temp = p;
            if (p->parent->lchild == p) p->parent->lchild = p->rchild;
            else p->parent->rchild = p->rchild;
            delete temp;
            temp = NULL;
        }
        else if (NULL == p->rchild)
        {
            Node *temp = p;
            if (p->parent->lchild == p) p->parent->lchild = p->lchild;
            else p->parent->rchild = p->lchild;
            delete temp;
            temp = NULL;
        }
        else    //左右孩子均不为空
        {
            Node *pre = Predecessor(p);
            int data = pre->data;
            Delete(data);        
            p->data = data;
        }
    }
    else
    {
        cout<<"the element do not exist, deletion failed"<<endl;
    }
}

Node *CBST::Predecessor(Node *p)
{
    if (!(p->lchild)) return p;
    else
    {
        p = p->lchild;
        while (p->rchild)
        {
            p = p->rchild;
        }

        return p;
    }
}

void CBST::HierarchyShow()
{
    if (NULL == T)
    {
        cout<<"empty"<<endl;
    }
    else
    {
        queue<Node *> nodeq;
        cout<<T->data<<" ";
        if (T->lchild) nodeq.push(T->lchild);
        if (T->rchild) nodeq.push(T->rchild);

        while (!nodeq.empty())
        {
            Node *p = nodeq.front();
            nodeq.pop();

            cout<<p->data<<" ";
            if (p->lchild) nodeq.push(p->lchild);
            if (p->rchild) nodeq.push(p->rchild);
        }

        cout<<endl;
    }
}

CBST::~CBST()
{
    //遍历释放节点空间,略
}

int main()
{
    vector<int> src;
    cout<<"请输入整形数组:";
    int temp;
    while (cin>>temp)
    {
        src.push_back(temp);
    }

    cin.clear();                
    cin.sync();     //需清缓冲,否则无法二次使用cin

    CBST bst(src);
    bst.HierarchyShow();

    int i;
    while(cin>>i)
    {
        vector<int> cpy(src);
        CBST bcpy(cpy);
        bcpy.Delete(i);
        bcpy.HierarchyShow();

        cout<<endl;
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值