二叉搜索树的创建 查找 删除

///此处省去概念若干字~ 欢迎指错
#include <iostream>
#include<queue>
using namespace std;

typedef struct treenode
{
    int data;
    treenode *lchild;
    treenode *rchild;
}node;
int flag = -1;
void insert_node(node* root, node* child)
{
     ///要插的子树不为空

    if(root->data >= child->data && root->lchild != NULL)
    {
        insert_node(root->lchild, child);
        return;
    }

    if(root->data < child->data && root->rchild != NULL)
    {
        insert_node(root->rchild, child);
        return ;
    }
    ///要插的子树为空 刚好可以插入
   if(root->data >= child->data && root->lchild == NULL)///一定要注意这两种情况的先后顺序
        root->lchild = child;
   if(root->data < child->data && root->rchild == NULL)///我刚开始就写反了 程序就崩了
        root->rchild = child;                       ///因为下面这种情况执行之后 孩子就不空了 那么第二个条件
}                                                      ///就一定成立了 然后就悲催的死循环了
void createTree(node **root, int *arr, int n)///建树
{
    (*root) = new node;
    (*root)->data = arr[0];
    (*root)->lchild = NULL;
    (*root)->rchild = NULL;
    node *child;
    for(int i=1; i<n; i++)
    {
        child = new node;
        child->data = arr[i];
        child->lchild = NULL;
        child->rchild = NULL;
        insert_node(*root, child);

    }
}
void in(node *root)
{
    if(root)
    {
        if(root->lchild)
            in(root->lchild);
        cout << root->data << ' ';
        if(root->rchild)
            in(root->rchild);
    }

}
void print(int *arr, int n)
{
    for(int i=0; i<n; i++)
    {
        cout << arr[i] <<' ';
    }
}
node* search_node(node *root, int e)///找值为X的节点
{
    queue<node *>q;
    node *a;
    if(root)
    {

        while(!q.empty())
            q.pop();
        q.push(root);
        while(!q.empty())
        {
            a = q.front();
            q.pop();
            if(a->data == e)
            {
                return a;
            }
            else
            {    ///注意啦注意啦 在对节点 或者 他的左右孩子做什么操作之前 尽量判断一下他是不是空的
                if(a->lchild)/// 卡在这好一会啊
                    q.push(a->lchild);
                if(a->rchild)
                    q.push(a->rchild);
            }
        }
    }
    return NULL;
}
void level(node *root)
{
    queue<node *>q;
    node *a;
    if(root)
    {
        while(!q.empty())
            q.pop();
        q.push(root);
        while(!q.empty())
        {
            a = q.front();
            q.pop();
            cout << a->data << ' ';
            if(a->lchild)
                q.push(a->lchild);
            if(a->rchild)
                q.push(a->rchild);
        }
    }
}
node* parent1(node *root, int e)
{
    queue<node *>q;
    node *a;
    node *p = search_node(root, e);
    if(root)
    {
        while(!q.empty())
            q.pop();
        q.push(root);
        while(!q.empty())
        {
            a = q.front();
            q.pop();     ///这里得加一个判断是左孩子还是右孩子的flag 以便在删除中进行判断
            if(a->lchild && a->lchild->data == e)
            {
                flag = 0;
                return a;
            }
            if(a->rchild && a->rchild->data == e)
            {
                flag = 1;
                return a;
            }
            else
            {
                if(a->lchild)
                    q.push(a->lchild);
                if(a->rchild)
                    q.push(a->rchild);
            }
        }
    }
    return NULL;
}

void delete_node(node **root, int e)
{
    node *p = search_node(*root, e);///找到了要删的节点 接下来进行判断 执行下一步操作
    node *q = parent1(*root, e);
    if(p == NULL)///1
    {
        cout << "not founded!" << endl;
        return ;
    }
    ///2.要删除的节点没有左右孩子,有父节点。
    if(p->lchild == NULL && p->rchild == NULL && q)
    {
        cout << p->data << endl;
        if(flag == 0)///节点 是左孩子
        {
            q->lchild = NULL;
            delete p;
        }
        else if(flag == 1)
        {
            q->rchild == NULL;
            delete p;
        }
    }
    ///3.要删除的node没有左右孩子,没有父节点(即根节点)。
    else if(p->lchild == NULL && p->rchild == NULL && !q)
    {
        (*root) = NULL;
        delete p;
    }
    ///4.要删除的node有左孩子没右孩子,有父节点
    else if(p->lchild && p->rchild == NULL && q)
    {
        if(flag == 0)
        {
            q->lchild = p->lchild;
            delete p;
        }
        else if(flag == 1)
        {
            q->rchild = p->lchild;
            delete p;
        }
    }
    ///5.有左右孩子 没父节点
    ///设定 将node 的右孩子插到它的左孩子里
    if(p && p->lchild && p->rchild && !q)
    {
        ///cout << "1" << endl;
        node * temp;
        temp = p;
        while(temp->lchild)
        {
            temp = temp->lchild;
            ///cout << "1" << endl;
        }
        temp->lchild = p->rchild;
        ///cout << "1" << endl;
        delete p;
        ///cout << "1" << endl;
        (*root) = temp;///一直崩 崩到我开始怀疑人生 因为忘改根节点了 改了就好了
    }
    ///6.要删除的node有右孩子没左孩子,有父节点
    ///这是怎么了 突然胃好疼 不行 我要写完
    else if(p->rchild && p->lchild==NULL &&q)
    {
        if(flag == 0)
        {
            q->lchild = p->rchild;
            delete p;
        }
        else if(flag == 1)
        {
            q->rchild = p->rchild;
            delete p;
        }
    }
     ///7.要被删除的node有右孩子没有左孩子,没有父节点
    else if(p->rchild && p->lchild ==NULL && !q)
    {

            (*root) = p->rchild;
            delete p;
    }
     ///8.要被删除的node左右孩子都有,有父节点
    else if(p->lchild && p->rchild && q)
    {
        if(flag == 0)
        {
            p->lchild->rchild = p->rchild;
            q->lchild = p->lchild;
            delete p;

        }
        else if(flag == 1)
        {
            p->rchild->lchild = p->lchild;
            q->rchild = p->rchild;
            delete p;
        }
    }

}
int main()
{
    int arr[11]={4,1,45,78,345,23,12,3,6,21};
    ///为了和中序遍历产生对比 我们打印一下数组
    int n = 10;
    cout << "the array is : " << endl;
    print(arr, n);
    cout << endl;
    node *parent = NULL;
    node *root = NULL;
    flag = -1;
    ///建树
    createTree(&root,arr, n);  ///采用先建立根节点 然后按序一个一个插得方式建立二叉搜索树
    ///中序遍历BST     呵呵哒   此时我想到了BTS
    cout << "the in_order is:"<< endl;
    in(root);
    cout << endl;
    /*int s;
    cin >> s;
    node *p  = search_node(root, s);///先找个节点 一会删除用
    if(p)
    {
        cout << p->data << endl;
    }
    else
    {
        cout << "NULL" << endl;
    }
    ///找某个节点的双亲结点 删除的必备函数 测试一下
    p = parent1(root, s);/// parent不能用作函数名 我有点方
    if(p)
    {
        cout << p->data << endl;
        cout << flag << endl;
    }
    else
    {
        cout << "NULL" << endl;
    }
    */
    int s;
    ///接下来就是最难的部分啦
    ///调用查找函数再找一遍吧
    ///那么接下来就对所有可能删除的情况进行测试吧

    while(cin >> s)
    {
        delete_node(&root, s);
        node *p = parent1(root, s);

        if(p && p->lchild)///这里竟然崩了 我很无语 睡一觉起来再说~  这里修改过了
        cout << p->lchild->data << endl;///原来写的是if(p->lchild) 没有判断双亲结点是否空 就崩了
        else
            cout << "NULL" << endl;/// 这个判断语句写的没什么意义 因为我已经把这个节点删了
                            ///输出肯定为空 但是它却帮我找出了错误 哈哈哈 不然我还得去麻烦大神
        cout << "the level_order is:" << endl;
        level(root);
        cout << endl;

    }
    ///1........1000
    ///2........6
    ///3........只有一个根节点的情况
    ///4&6 .........1
    ///5...........4
    ///7..........只有右孩子的根节点
    ///8..........45
    ///基本上就这么些情况了 如果缺的话 也就是左右孩子的问题了, 类比一下是很好解决的
    return 0;
}
///两天啦 终于解决了 但是写的太慢了 估计以后写的时候还会很慢 唉 
/*
the array is :
4 1 45 78 345 23 12 3 6 21
the in_order is:
1 3 4 6 12 21 23 45 78 345
1000
not founded!
NULL
the level_order is:
4 1 45 3 23 78 12 345 6 21
6
6
NULL
the level_order is:
4 1 45 3 23 78 12 345 21
1
NULL
the level_order is:
4 3 45 23 78 12 345 21
45
NULL
the level_order is:
4 3 78 23 345 12 21
4
NULL
the level_order is:
3 78 23 345 12 21
taekwoon oppa salanghei
*/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值