AVL平衡二叉树C++版

#include <iostream>
using namespace std;

class AVLNode{
public:
    int data;
    int height;//结点的高度,叶子结点高度为1 
    AVLNode* lChild;
    AVLNode* rChild;
public:
    AVLNode(int data):data(data),height(1),lChild(0),rChild(0){} 
};

class AVL{
public:
    AVLNode* root;
public:
    AVL(){
        root = nullptr;
    }
    ~AVL(){
        delete root;
    }
    int height(AVLNode* root){
        if(root){
            return root->height;
        }
        return 0;
    } 
    //找到树中最大结点并将其返回 
    AVLNode* finMaxNode(AVLNode* root){
        //一直往右找 
        if(root->rChild){
            root = root->rChild;
        } 
        return root;
    }
    //找到树中最小结点并将其返回 
    AVLNode* finMinNode(AVLNode* root){
        //一直往左找 
        if(root->lChild){
            root = root->lChild;
        } 
        return root;
    }
    //以p为根结点右旋转,返回新的根结点 
    AVLNode* llRotate(AVLNode* p){
        AVLNode* pleft = p->lChild;
        p->lChild = pleft->rChild;
        pleft->rChild = p;  
        //结点的高度由该节点的子树唯一决定,所以只有子树发生变化的结点才需要更新高度值 
        pleft->height = max(height(pleft->lChild), height(pleft->rChild))+1;
        p->height = max(height(p->lChild), height(p->rChild))+1;
        return pleft; 
    }
    //左旋转 
    AVLNode* rrRotate(AVLNode* p){
        AVLNode* pright = p->rChild;
        p->rChild = pright->lChild;
        pright->lChild = p; 
        pright->height = max(height(pright->lChild), height(pright->rChild))+1;
        p->height = max(height(p->lChild), height(p->rChild))+1;
        return pright; 
    }
    //先左,再右 
    AVLNode* lrRotate(AVLNode* p){
        AVLNode* pleft = rrRotate(p->lChild);
        return llRotate(p);
    }
    //先右,再左 
    AVLNode* rlRotate(AVLNode* p){
        AVLNode* pright = llRotate(p->rChild);
        return rrRotate(p);
    }
    //插入新结点,保持平衡 
    void insert(int data, AVLNode*& root){
        if(!root){ 
            root = new AVLNode(data);
        }
        else{
            if(data < root->data){
                insert(data, root->lChild);
                //插入新结点后,如果打破平衡,则需要动态调整 
                if(height(root->lChild)-height(root->rChild) == 2){
                    if(data < root->lChild->data)
                        root = llRotate(root);
                    else
                        root = lrRotate(root);
                }
            }
            else if(data > root->data){
                insert(data, root->rChild);
                //插入新结点后,如果打破平衡,则需要动态调整 
                if(height(root->rChild)-height(root->lChild) == 2){
                    if(data > root->rChild->data)
                        root = rrRotate(root);
                    else
                        root = rlRotate(root);
                }
            }
            else{
                cout << "AVL中已存在该值:" << data << endl;
            }
        }
        //平衡后,需要更新根结点的高度值
        root->height = max(height(root->lChild), height(root->rChild))+1;
    }
    //删除结点,保持平衡 
    void del(int data, AVLNode*& root){
        if(data < root->data){
            del(data, root->lChild);
            //删除点之后,若AVL树失去平衡,则进行调整
            if(height(root->rChild)-height(root->lChild) == 2){
                AVLNode* r = root->rChild;
                if(height(r->lChild) > height(r->rChild))
                    root = rlRotate(root);
                else
                    root = rrRotate(root);
            } 
        }
        else if(data > root->data){
            del(data, root->rChild);
            //删除点之后,若AVL树失去平衡,则进行调整
            if(height(root->lChild)-height(root->rChild) == 2){
                AVLNode* l = root->lChild;
                if(height(l->lChild) > height(l->rChild))
                    root = llRotate(root);
                else
                    root = lrRotate(root);
            }
        }
        else{
            //此时root为要删除的点 
            if(root->lChild && root->rChild){
                if(height(root->lChild) > height(root->rChild)){
                    // 如果root的左子树比右子树高;
                    // 则(01)找出root的左子树中的最大节点
                    //   (02)将该最大节点的值赋值给root。
                    //   (03)删除该最大节点。
                    // 这类似于用"root的左子树中最大节点"做"root"的替身;
                    // 采用这种方式的好处是:删除"tree的左子树中最大节点"之后,AVL树仍然是平衡的。
                    AVLNode* maxNode = finMaxNode(root->lChild);
                    root->data = maxNode->data;
                    del(maxNode->data, root->lChild);
                }
                else{
                    AVLNode* minNode = finMinNode(root->rChild);
                    root->data = minNode->data;
                    del(minNode->data, root->rChild);
                }
            }
            else{
                if(root->lChild){
                    root->data = root->lChild->data;
                    root->lChild = nullptr;
                }   
                else if(root->rChild){
                    root->data = root->rChild->data;
                    root->rChild = nullptr;
                }
                else{
                    root = nullptr;//参数是引用,所以此处修改了主函数中的root值 
                }
            }
        }
    }
    void inOrder(AVLNode* root){
        if(root){
            inOrder(root->lChild);
            cout << root->data << endl;
            inOrder(root->rChild);
        }
    }
};

int main(){
    AVL tree;
    tree.insert(5, tree.root);
    tree.insert(15, tree.root);
    tree.insert(25, tree.root);
    tree.insert(35, tree.root);
    tree.insert(45, tree.root);
    tree.insert(55, tree.root);
    tree.del(55, tree.root);
    tree.inOrder(tree.root);
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/vaemusicsky/article/details/81607251