DS二叉排序树之删除

题目描述

给出一个数据序列,建立二叉排序树,并实现删除功能

对二叉排序树进行中序遍历,可以得到有序的数据序列

输入

1
6
22 33 55 66 11 44
3
66
22
77

第一行输入t,表示有t个数据序列

第二行输入n,表示首个序列包含n个数据

第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开

第四行输入m,表示要删除m个数据

从第五行起,输入m行,每行一个要删除的数据,都是自然数

以此类推输入下一个示例

输出

11 22 33 44 55 66 
11 22 33 44 55 
11 33 44 55 
11 33 44 55 

第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到

从第二行起,输出删除第m个数据后的有序序列,输出m行

以此类推输出下一个示例的结果

提示

当删除数据不在序列中,那么删除操作等于不执行,所以输出序列不变化

在这位大佬的基础上进行了改进,更适合技大宝宝的体质半濠春水icon-default.png?t=N4N7https://blog.csdn.net/weixin_51571728

#include <iostream>
using namespace std;
class Binary_tree_node
{
public:
    int data;
    Binary_tree_node* lChild, * rChild, * parents;
    Binary_tree_node() : lChild(NULL), rChild(NULL) { parents = NULL; data = 0; }
    Binary_tree_node(int e) : data(e), lChild(NULL), rChild(NULL), parents(NULL) {}
    ~Binary_tree_node(){}
};
class Binary_tree
{
    Binary_tree_node* root;

    void InsertNode(int data, Binary_tree_node*& r)//插入节点
    {
        if (data > r->data && r->rChild)
        {
            InsertNode(data, r->rChild);
        }
        else if (data < r->data && r->lChild)
        {
            InsertNode(data, r->lChild);
        }
        else if (data > r->data && !r->rChild)//建立右节点
        {
            Binary_tree_node* s = new Binary_tree_node(data);
            r->rChild = s;
            s->parents = r;
        }
        else if (data < r->data && !r->lChild)//建立左节点
        {
            Binary_tree_node* s = new Binary_tree_node(data);
            r->lChild = s;
            s->parents = r;
        }
    }
    Binary_tree_node* getBefore(Binary_tree_node* s)//找到左子树中最右的节点
    {
        Binary_tree_node* p = s->lChild;
        while (p->rChild)
        {
            p = p->rChild;
        }
        return p;
    }
    void InOrder(Binary_tree_node* t)//中序输出
    {
        if (t)
        {
            InOrder(t->lChild);
            cout << t->data << " ";
            InOrder(t->rChild);
        }
    }
    void Delete(int key, Binary_tree_node* t)
    {
        if (key > t->data && t->rChild)
        {
            Delete(key, t->rChild);
        }
        else if (key < t->data && t->lChild)
        {
            Delete(key, t->lChild);
        }
        else if (key == t->data)
        {
            if (!t->lChild && !t->rChild)//删除叶子节点
            {
                if (t->parents->lChild != NULL && t->parents->lChild->data == t->data)//要将父节点对应的节点设为NULL不然会出现野指针(指向的节点被删除)
                    t->parents->lChild = NULL;
                else
                    t->parents->rChild = NULL;
                delete t;
                t = NULL;
            }
            else if (t->lChild && !t->rChild)//删除的节点只有左子树
            {
                if (t->parents == NULL)//根节点要单独删除
                {
                    root = t->lChild;
                    t->lChild->parents = NULL;
                    delete t;
                    t = NULL;
                    return;
                }
                if (t->parents->lChild != NULL && t->parents->lChild->data == t->data)
                {
                    t->parents->lChild = t->lChild;
                    t->lChild->parents = t->parents;
                }
                else
                {
                    t->parents->rChild = t->lChild;
                    t->lChild->parents = t->parents;
                }
                delete t;
                t = NULL;
            }
            else if (t->rChild && !t->lChild)//删除的节点只有右子树
            {
                if (t->parents == NULL)//根节点要单独删除
                {
                    root = t->rChild;
                    t->rChild->parents = NULL;
                    delete t;
                    t = NULL;
                    return;
                }
                if (t->parents->lChild != NULL && t->parents->lChild->data == t->data)
                {
                    t->parents->lChild = t->rChild;
                    t->rChild->parents = t->parents;
                }
                else
                {
                    t->parents->rChild = t->rChild;
                    t->rChild->parents = t->parents;
                }
                delete t;
                t = NULL;
            }
            else if (t->lChild && t->rChild)//若左右都有,则删除左子树中最右的节点
            {
                Binary_tree_node* p = getBefore(t);
                int d = p->data;//删除后把原本需要删除的子树的值改为被删除节点的值
                Delete(d, p);
                t->data = d;
            }
        }
    }
public:
    Binary_tree(int data) { root = new Binary_tree_node(data); }
    void Delete(int key)
    {
        Delete(key, root);
    }
    void Insert(int key)
    {
        InsertNode(key, root);
    }
    void InOrder()
    {
        InOrder(root);
        cout << endl;
    }
};

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n, m;
        cin >> n;
        int data;
        cin >> data;
        Binary_tree bt(data);
        for (int i = 1; i < n; i++)
        {
            cin >> data;
            bt.Insert(data);
        }
        bt.InOrder();
        cin >> m;
        while (m--)
        {
            int key;
            cin >> key;
            bt.Delete(key);
            bt.InOrder();
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值