二叉搜索树的插入和删除

题目:2叉搜索树的插入和删除 
要求
(1)任意选顶一个2叉搜索树用先序遍历 中序遍历 和后序遍历显示该2叉搜索树

(2)动态显示出在2叉搜索树中插入一个元素时树的变化过程 要求演示出所有可能的情况

(3)动态显示出 在2叉搜索树中删除一个元素时的变化过程要求演示出所有的可能的情况 

#include <iostream.h>
#define max 10
struct BinTreeNode                                                                             //二叉查找树的节点结构体
{
    int m_data;
    struct BinTreeNode *lchild, *rchild;
    BinTreeNode(int item, BinTreeNode *left = NULL, BinTreeNode *right = NULL)
        : m_data(item), lchild(left), rchild(right)  //构造函数默认的lchild,rchild为NULL
    {
    }
};

class  BinaryTree                                                                       //二叉搜索树类
{

private:
    BinTreeNode *root;   //根节点指针

public:
    BinaryTree()
    {
        root = NULL;
    }
    
 //迭带插入的方法建二叉搜索树
    void Insert(const int node)                                                
    {                                     
        BinTreeNode *currentpointer;        //当前节点指针  
        BinTreeNode *parentpointer;         //父亲节点指针    
        BinTreeNode *newpointer; 
        //ptr必须为根节点指针的引用
        BinTreeNode *ptr = root;
        newpointer = new BinTreeNode(node); //新动态分配一个节点

        if(root == NULL)    //如果此时树为空,返回新开辟的节点
        {
            root = newpointer;
        }
        else
        {
            currentpointer = ptr;        //保存root指针
   //一直移动到是使parentpointer指向叶子节点而currentpointer为NULL
            while(currentpointer != NULL)    //当当前节点不为空的情况下
            {
                parentpointer = currentpointer; //用指向父亲节点的指针保存当前指针

                if(currentpointer->m_data > node)
                {
                    currentpointer = currentpointer->lchild;
                }
                else
                {
                    currentpointer = currentpointer->rchild;
                }
            }
            //以下是将节点插入
            if(parentpointer->m_data > node)
            {
                parentpointer->lchild = newpointer;
            }
            else
            {
                parentpointer->rchild = newpointer;
            }
        }
    }

 //创建方法,依次插入
    BinTreeNode *Creat(int data[],int len) 
    {
        for(int i=0; i<len; i++)
        {
            Insert(data[i]);
        }
        return root;
    }
    
    void PreOrder()
    {
        cout<<"前序遍历的结果为:";
        PrePrint(root);
    }

    void InOrder()
    {
        cout<<"中序遍历的结果为:";
        InPrint(root);
    }

    void PostOrder()
    {
        cout<<"后序遍历的结果为:";
        PostPrint(root);
    }

    void Count()
    {
        cout<<endl;
        cout<<"叶子节点数为:"<<CountLeafs(root)<<endl;
    }

    void PrePrint(BinTreeNode *p) //前序遍历
    {
        if(p != NULL)
        {
            cout << p->m_data << ',';
            PrePrint(p->lchild);
            PrePrint(p->rchild);
        }
    }

    void InPrint(BinTreeNode *p)  //中序遍历
    {
        if(p != NULL)
        {
            InPrint(p->lchild);
            cout<< p->m_data<<',';
            InPrint(p->rchild);
        }
    }
    
    
    void PostPrint(BinTreeNode *p)  //后序遍历
    {
        if(p != NULL)
        {
            PostPrint(p->lchild);
            PostPrint(p->rchild);
            cout<< p->m_data<< ',';
        }
    }

    BinTreeNode * Find(const int &c)  //用迭带的方法寻找特定的节点
    {
        BinTreeNode *pCurrent = root;
        if(pCurrent  != NULL)
        {
            while(pCurrent  != NULL)
            {
                if(pCurrent->m_data == c)
                {
                    return pCurrent;
                }
                else 
                {
                    if(c > pCurrent->m_data)
                        pCurrent  = pCurrent->rchild;
                    else
                        pCurrent  = pCurrent ->lchild;
                }
            }
        }
        return NULL;
    }
    
    bool DeleteBT(const int &key)   //删除节点的函数定义
    {
        BinTreeNode *q, *s;
        BinTreeNode *current = root; //找到要删除的节点
        BinTreeNode *prt = NULL;    //current的父亲节点

        while ((NULL != current) && (current->m_data != key))
                                   //通过查找找到值为key的节点和它的父亲节点
        {
            prt = current;
              
             if (current->m_data > key)
                     current = current->lchild;
             else
                     current = current->rchild;
        }

        if(current == NULL) //current为NULL说明节点不存在
        {
            cout<<"没有此节点!"<<endl;
            return false;
        }
        if(current->lchild == NULL && current->rchild == NULL)
                       //当找到的节点即没有左孩子也没有右孩子
        {
            if(current == root)
            {
                root = NULL;
            }
            else 
            {
                if(current == prt->lchild)
                {
                    prt->lchild = NULL;
                }
                else
                {
                    prt->rchild = NULL;
                }
            }
        }
        if(current->lchild == NULL && current->rchild != NULL)
                        //当找到的节点有右孩子而没有左孩子
        {
            if(current == root)
            {
                current = current->rchild;
            }
            else 
            {
                if(current == prt->lchild)  //如果当前节点是prt指向节点的左孩子
                {
                    prt->lchild = current->rchild;
                }
                else
                {
                    prt->rchild = current->rchild;
                }
            }
        }
        if(current->rchild == NULL && current->lchild != NULL) 
                                        //如果当前节点有左孩子而没有右孩子
        {
            if(current == root)
            {
                current = current->lchild;
            }
            else
            {
                if(current == prt->lchild)
                {
                    prt->lchild = current->lchild;
                }
                else
                {
                    prt->rchild = current->lchild;
                }
            }
        }

        if(current ->lchild != NULL && current->rchild != NULL)//当前节点左右孩子都有
        {
            q = current;    //用q保存current节点指针
            s = current;    //s是current的前驱指针

            current = current->lchild;
            //先向左走
            while(current->rchild) //然后向右走到尽头,其实就是寻找左子树当中最大的节点
            {                      //补充:寻找右子树当中最小的节点也是可以的
                s = current;       //s指向current的前驱
                current = current->rchild;
            }

            q->m_data = current->m_data;  //用找到的节点替换当前节点
        
            if(q != s)                    //将current节点从树中拆下来
                s->rchild = current->lchild;
            else
                q->lchild = current->lchild;
        }
        delete current;        //释放current指向的空间
        current = NULL;
        return true;
    }

    void destroy(BinTreeNode *current) //销毁二叉树
    {
        if(current != NULL)
        {
            destroy(current->lchild);
            destroy(current->rchild);
            delete current;
            current = NULL;
        }
    }

    int CountLeafs(BinTreeNode *current)
    {
        if(current == NULL)
        {
            return 0;
        }
        else 
        {
            if( current->lchild == NULL  &&  current->rchild == NULL )
            {
                return 1;
            }
            else
            {
                int num1 = CountLeafs(current->lchild);
                int num2 = CountLeafs(current->rchild);
                return (num1+num2);
            }
        }
    }

    virtual  ~BinaryTree() 
    {
        destroy(root);
    }
};
void main()
{
    BinaryTree myTree;
    int a[]={6, 3, 4, 7, 8, 2, 5, 9, 0, 1};
 //输出
 cout<<"(1)输出部分:"<<endl;
    myTree.Creat(a, max);  //创建二叉搜索树
    myTree.PreOrder();     //先序遍历
 cout<<endl;
    myTree.InOrder();      //中序遍历
 cout<<endl;
    myTree.PostOrder();    //后序遍历
 cout<<endl<<endl;
 //插入
 cout<<"(2)插入部分:"<<endl;
 int x;
 cout<<"输入你想要插入的节点:";
 cin>>x;
 myTree.Insert(x);
 myTree.InOrder();      //中序遍历
    cout<<endl<<endl;

 //删除
 cout<<"(3)删除部分:"<<endl;
    cout<<"输入一个你想删除的节点: ";
    cin>>x;
    if(myTree.DeleteBT(x))  //进行删除
        cout<<"删除成功!"<<endl;
    else
        cout<<"删除失败!"<<endl;
    myTree.InOrder();      //中序遍历
 cout<<endl<<endl;

 //查询
 cout<<"(4)查询部分:"<<endl;
 cout<<"输入你想要找的节点";
    cin>>x;
    if(myTree.Find(x))     //进行查找
        cout<<"查找成功!"<<endl;
    else
        cout<<"查找失败!"<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值