5/2 二分搜索树

 

#include <iostream>
#include <queue>
#include <cassert>
using namespace std;

template <typename Key,typename Value>
class BST{
private:
    struct Node{   //定义节点
        Key key;
        Value value;
        Node* left;
        Node* right;

        Node(Key key,Value value)
        {
            key=key;
            value=value;
            left=nullptr;
            right=nullptr;
        }
        Node(Node* node)
        {
            key=node->key;
            value=node->value;
            left=node->left;
            right=node->right;
        }
    };
    Node* root;  //BST的根
    int cnt;  //BST中节点的个数

public:
    BST() //构造函数
    {
        root=nullptr;
        cnt=0;
    }

    ~BST() //析构函数
    {
        __destory(root);

    }

    int sz()
    {
        return cnt;
    }

    bool isEmpty()
    {
        return cnt==0;
    }

    //向二叉搜索树种插入元素
    void myInsert(Key key,Value value)
    {
        root=__insert(root,key,value);
    }

    //判断二叉搜索树种是否包含某个元素
    bool myContain(Key key)
    {
        return __myContain(root,key);
    }

    Value* mySearch(Key key)
    {
        return __mySearch(root,key);
    }

    //前序遍历
    void preOrder()
    {
        __preOrder(root);
    }

    //中序遍历
    void inOrder()
    {
        __inOrder(root);
    }

    //层序遍历
    void levelOrder()
    {
        if(node==nullptr)
            return;
        queue<Node*> qu;
        qu.push(root);
        while(!qu.empty())
        {
            Node* node=qu.front();
            qu.pop();
            cout<<node->key<<endl;
            if(node->left)
                qu.push(node->left);
            if(node->right)
                qu.push(node->right);
        }
    }

    //寻找最小的键
    Key minimum()
    {
        assert(cnt>0);
        Node* node= __minimum(root);
        return node->key;
    }

    //寻找最大的键
    Key minimum()
    {
        assert(cnt>0);
        Node* node= __maximum(root);
        return node->key;
    }



  //从二叉搜索树种删除最小值所在的节点
  void removeMin()
  {
      if(root)
      {
          root=__removeMin(root);
      }
  }

  //从二叉搜索树种删除最大值所在的节点
  void removeMax()
  {
      if(root)
      {
          root=__removeMax(root);
      }
  }


  //二叉树中删除键值为key的节点
  void myRemove(Key key)
  {
      root=__myRemove(root,key);
  }

private:
    //向以node为根的二叉搜索树中,插入节点(key,value)
    //返回插入新节点后的二叉搜索树的根
    Node* __insert(Node* node,Key key,Value value)
    {
        if(node==nullptr)  //根节点为空,直接生成一个节点并返回
        {
            cnt++;
            return new Node(key,value);
        }

        if(key==node->key)  //等于node->key,更新值即可
        {
            node->value=value;
        }
        else if(key<node->key)  //小于,往左孩子中插入
        {
            node->left=__insert(node->left,key,value);
        }
        else   //大于,往右孩子中插入
        {
            node->right=__insert(node->right,key,value);
        }
        return node;
    }

    //判断以node为根的二叉搜索树中是否存在node
    bool __myContain(Node* node,Key key)
    {
        if(node==nullptr)
            return false;
        if(node->key==key)
        {
            return true;
        }
        else if(key<node->key)
        {
            return __myContain(node->left,key);
        }
        else
        {
            return __myContain(node->right,key);
        }
    }


    //在以node为根的二叉搜索树中查找key
    Value* __mySearch(Node* node,Key key)
    {
        if(node==nullptr)
        {
            return nullptr;
        }
        if(node->key==key)
        {
            return &(node->value);
        }
        else if(key < node->key)
        {
            return __myContain(node->left,key);
        }
        else
        {
            return __myContain(node->right,key);
        }
    }

    void __preOrder(Node* node)
    {
        if(node==nullptr)
        {
            return;
        }
        cout<<node->key<<endl;
        __preOrder(node->left);
        __preOrder(node->right);

    }

    void __inOrder(Node* node)
    {
        if(node==nullptr)
        {
            return;
        }
        __inOrder(node->left);
        cout<<node->key<<endl;
        __inOrder(node->right);

    }


    void __destory(Node* node)
    {
        if(node==nullptr)
        {
            return;
        }
        __destory(node->left);
        __destory(node->right);
        delete node;
        cnt--;
    }


    Node* __minimum(Node* node)
    {
        if(node->left==nullptr)
        {
            return node;
        }
        return __minimum(node->left);
    }

    Node* __maximum(Node* node)
    {
        if(node->right==nullptr)
        {
            return node;
        }
        return __maximum(node->right);
    }



    //删除掉以node为根的二分搜索树中的最小节点
    //返回删除节点后新的二分搜索树的根
    Node* __removeMin(Node* node)
    {
        if(node->left==nullptr)
        {
            Node* rightNode=node->right;
            delete node;
            cnt--;
            return rightNode;
        }
        node->left=__removeMin(node->left);

        return node;
    }


     //删除掉以node为根的二分搜索树中的最大节点
    //返回删除节点后新的二分搜索树的根
    Node* __removeMax(Node* node)
    {
        if(node->right==nullptr)
        {
            Node* leftNode=node->left;
            delete node;
            cnt--;
            return leftNode;
        }
        node->right=__removeMax(node->right);

        return node;
    }


    //删除掉以node为根的二分搜索树中键值为key的节点
    //返回删除节点后新的二分搜索树的根
    Node* __myRemove(Node* node,Key key)
    {
        if(node==nullptr)
        {
            return nullptr;
        }
        if(key<node->key)
        {
            node->left=__myRemove(node->left,key);
            return node;
        }
        else if(key>node->key)
        {
            node->right=__myRemove(node->right,key);
            return node;
        }
        else   //要删除当前节点,首先判断左右孩子是否有是空的
        {
            if(node->left==nullptr)
            {
                Node* rightnode=node->right;
                delete node;
                cnt--;
                return rightnode;
            }
            if(node->right==nullptr)
            {
                Node* leftnode=node->left;
                delete node;
                cnt--;
                return leftnode;
            }
            //左右子树都不为空
            //找到node右子树的最小值,替换node
            Node* successor=new Node(minimum(node->right));  //复制该节点
            cnt++;

            //左孩子是原来节点的左孩子
            successor->left=node->left;

            //右孩子是删除掉最小节点后返回的根节点
            successor->right=removeMin(node->right);

            delete node;
            cnt--;

            return successor;
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值