平衡二叉搜索树

来源:互联网 发布:黄海真实故事知乎 编辑:程序博客网 时间:2024/04/30 04:26

写完之后从来没用过……

#include <cstdio>#include <algorithm>using namespace std;template <typename T>class avl {private:    class node{    public:        node* left;        node* right;        int height;        //该子树所含节点的个数        int size;        T data;        node():left(NULL) ,right(NULL),height(0),size(0){};        node(T data,node* left=NULL,node* right=NULL) : data(data),left(left),right(right), height(1),size(1){};        int getHeight(){return this?height:0;}        int getSize(){ return this?size:0; }        void update(){            if(this){                height=max(left->getHeight(),right->getHeight())+1;                size=left->getSize()+right->getSize()+1;            }        }    }*root;    //左单旋转    void leftSingleRotate(node *&p) {        node* t=p->right->left;        p->right->left=p;        p=p->right;        p->left->right=t;        p->left->update();        p->update();    }    //右单旋转    void RightSingleRotate(node *&p) {        node* t=p->left->right;        p->left->right=p;        p=p->left;        p->right->left=t;        p->right->update();        p->update();    }    //平衡化旋转    void balanceRotate(node *&p) {        int leftHeight,rightHeight;        //平衡左子树        if(p->left->getHeight()>p->right->getHeight()+1){            leftHeight = p->left->left->getHeight();            rightHeight = p->left->right->getHeight();            //三个节点处于一条直线上(左下到右上),进行右单旋转            if(leftHeight >= rightHeight)RightSingleRotate(p);            //三个节点处于一条直线上,进行先左后右双旋转            else {                leftSingleRotate(p->left);                RightSingleRotate(p);            }        }        //平衡右子树        if(p->right->getHeight()>p->left->getHeight()+1){            leftHeight=p->right->left->getHeight();            rightHeight=p->right->right->getHeight();            //三个节点处于一条直线上(右下到左上),进行左单旋转            if(rightHeight>=leftHeight)leftSingleRotate(p);             //三个节点处于一条直线上,进行先右后左双旋转            else {                RightSingleRotate(p->right);                leftSingleRotate(p);            }        }    }    //以p为根的子树删除data    void erase(node * & p, T data) {        if(p){            if(p->data==data){                if(p->left&&p->right){                    node* t=p->right;                    //找到中序遍历下的直接前驱                    while(t->left) t=t->left;                    //把t的内容传给p                    p->data=t->data;                    //转化从p的右子树删除t,t最多有一个子树                    erase(p->right,t->data);                    balanceRotate(p);                }else if(p->left){                    p->data=p->left->data;                    p->left=NULL;                }else if(p->right){                    p->data=p->right->data;                    p->right=NULL;                } else                    p=NULL;                p->update();            }else if(data<p->data) erase(p->left,data);            else erase(p->right,data);            balanceRotate(p);            p->update();        }    }    void insert(node*& p,T data){        if(p){            if(data<= p->data) insert(p->left,data);            else insert(p->right,data);            balanceRotate(p);            p->update();        }else p = new node(data);    }public:    avl() : root(NULL) {};    void insert(T data) { insert(root, data); }    void erase(T data) { erase(root, data); }    void clear(node * p) {        if(!p)return;        clear(p->left);        clear(p->right);        delete p;    }    bool empty() { return (root->getSize() == 0); }    int size() { return root->getSize(); }    node* getRoot() { return root; }};
原创粉丝点击