二分搜索树常见操作(C++版)

17 篇文章 9 订阅
8 篇文章 0 订阅
#include <iostream>
#include <algorithm>
#include <string>
#include <ctime>
#include <cmath>
#include <cassert>
#include <queue>

using namespace std;

template <typename Key,typename Value>
class BST{
public:
    BST(){
        root=NULL;
        Count=0;
    }

    ~BST(){
        destory(root);
    }

    int size(){
        return Count;
    }

    bool isEmpty(){
        return Count=0;
    }

    void Insert(Key key,Value value){
        root=Insert(root,key,value);
    }

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

    //前序遍历
    void preOrder(){
        preOrder(root);
    }
    //中序遍历
    void inOrder(){
        inOrder(root);
    }
    //后序遍历
    void postOrder(){
        postOrder(root);
    }
    //层序遍历
    void levelOrder(){
        queue<Node *>q;
        q.push(root);
        while(!q.empty()){
            Node *node=q.front();
            q.pop();

            cout<<node->key<<endl;
            if(node->left)
                q.push(node->left);
            if(node->right)
                q.push(node->right);
        }
    }

    //寻找最小的键值
    Key minimum(){
        assert(Count!=0);
        Node* minNode=minimum(root);
        return minNode->key;
    }
     //寻找最大的键值
    Key maximum(){
        assert(Count!=0);
        Node* maxNode=maximum(root);
        return maxNode->key;
    }

    //从二叉树中删除最小值所在的节点
    void removeMin(){
        if(root)
            root=removeMin(root);
    }
    //从二叉树中删除最大值所在的节点
    void removeMax(){
        if(root)
            root=removeMax(root);
    }

    //从二叉树中删除键值为key的节点
    void Remove(Key key){
        root=Remove(root,key);
    }
private:
    //向以node为根的二分搜索树中,插入节点(key,value)
    //返回插入新节点后的二分搜索树的根
    Node* Insert(Node *node,Key key,Value value){
        if(node==NULL){
            Count++;
            return new Node(key,value);
        }
        if(key==node->key)
            node->key=key;
        else if(key<node->key)
            node->left=Insert(node->left,key,value);
        else
            node->right=Insert(node->right,key,value);

        return node;
    }

    //查找以node为根的二分搜索树中是否包含键值为key的节点
    bool contain(Node *node,Key key){
        if(node==NULL)
            return false;
        if(key==node->key)
            return true;
        else if(key<node->key)
            return contain(node->left,key);
        else
            return contain(node->right,key);
    }

    //在以node为根的二分搜索树中查找key所对应的value
    Value* Search(Node *node,Key key){
        if(node==NULL)
            return NULL;

        if(key==node->value)
            return &(node->value);
        else if(key<node->key)
            return Search(node->left,key);
        else
            return Search(node->right,key);
    }

    //对以node为根的二分搜索树进行前序遍历
    void preOrder(Node *node){
        if(node !=NULL){
            cout<<node->key<<endl;
            preOrder(node->left);
            preOrder(node->right);
        }

    }
    //对以node为根的二分搜索树进行中序遍历
    void inOrder(Node *node){
        if(node!=NULL){
            inOrder(node->left);
            cout<<node->key<<endl;
            inOrder(node->right);
        }
    }
     //对以node为根的二分搜索树进行后序遍历
     void postOrder(Node *node){
        if(node!=NULL){
            postOrder(node->left);
            postOrder(node->right);
            cout<<node->key<<endl;
        }
     }

     //用类似后序遍历的方法释放空间
     void destory(Node *node){
        if(node !=NULL){
            destory(node->left);
            destory(node->right);

            delete(node);
            Count--;
        }
     }

     //在以node为根的二分搜索树中,返回最小键值的节点
     Node* minimum(Node* node){
        if(node->left == NULL)
            return node;
        return minimum(node->left);
     }
     //在以node为根的二分搜索树中,返回最大键值的节点
     Node* maximum(Node *node){
        if(node->right==NULL){
            return node;
        }
        return maximum(node->right);
     }

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

     //删除掉以node为根的二分搜索树中键值为key的节点
     //返回删除节点后新的二分搜索树的根O(logn)
     Node* Remove(Node* node,Key key){
        if(node == NULL)
            return NULL;
        if(key<node->key){
            node->left=Remove(node->left,key);
            return node;
        }
        else if(key>node->key){
            node->right=Remove(node->right,key);
            return node;
        }
        else{//key==node->key
            if(node->left==NULL){
                Node *rightNode=node->right;
                delete node;
                Count--;
                return rightNode;
            }
            if(node->right==NULL){
                Node *leftNode=node->left;
                delete node;
                Count--;
                return leftNode;
            }
            //node->left!=NULL && node->right!=NULL;
            Node *successor=new Node(minimum(node->right));
            Count++;
            successor->right=removeMin(node->right);
            successor->left=node->left;
            delete node;
            Count--;
            return successor;
        }

     }
private:
    struct Node{
        Key key;
        Value value;
        Node *left;
        Node *right;

        Node(Key key,Value value){
            this->key=key;
            this->value=value;
            this->left=this->right=NULL;
        }
        Node(Node *node){
            this->key=node->key;
            this->value=node->value;
            this->left=node->left;
            this->right=node->right;
        }
    };

    Node *root;//根节点
    int Count;//记录节点数
};


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rocky0429

一块也是爱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值