平衡树AVL

 需要注意的是删除结点,有时删除结点不会影响此结点所在层的平衡,如删除50,会在递归返回时判断出40的平衡受影响

当删除30时,用31补充。30所在层的平衡已经被破坏,需要马上调整。删除40也是

                 40

        30              70

    20   31        50

19

template<class T>
struct BinTree
{
    T data;
    BinTree* left, * right;
    //BinTree* parent;
    int height;
    BinTree(T e, int h = 1, BinTree* l = nullptr, BinTree* r = nullptr, BinTree* p = nullptr) :data(e) {
        left = l;
        right = r;
        //parent = p;
        height = h;
    }
};
template<class T>
class AVL {
    typedef BinTree<T> BTNode;
    //typedef BinTree<T> node_type;
    //typedef T elem_type;
public:
    BTNode* m_root;
    AVL() :m_root(nullptr){}//初始化为空树
    ~AVL() {
        destruct(m_root); m_root = nullptr;
    }
    void destruct(BTNode* T) {
        if (T != nullptr) {
            destruct(T->left);
            destruct(T->right);
            //cout << "destruct= " << T->data << endl;
            delete T;
        }
    }
    BTNode* find(T e) {
        if (m_root == nullptr)return nullptr;
        BTNode* root = m_root;
        while (root) {
            if (root->data == e)return root;
            else if (e > root->data)root = root->right;
            else root = root->left;
        }
        return nullptr;
    }
    void insert(T e) {
        //cout << "insert= " << e << endl;
        //my_preOrder(m_root); cout << endl;
        //my_inOrder(m_root); cout << endl;
        //my_floorOrder(m_root); cout << endl;
        m_root = insert(m_root, e);
    }
    void remove(T e) {
        //cout << "remove= " << e << endl;
        m_root = remove(m_root, e);
        //cout << "remove, end" << endl; cout << endl;
    }
private:
    BTNode* insert(BTNode* root, T e) {//经过平衡调整后结点可能会变,因此递归返回指针
        if (root ==nullptr) {//空树
            root = new BTNode(e);
            return root;
        }
        if (e == root->data)return root;
        else if (e < root->data) root->left = insert(root->left, e);
        else root->right = insert(root->right, e);

        root->height = max(getheight(root->left), getheight(root->right)) + 1;//重新计算高度
        root = adjustBanlence(root);//调整

        return root;
    }
    BTNode* adjustBanlence(BTNode* root) {//检查平衡因子并调整
        if(root==nullptr) return nullptr;
        int bf = getheight(root->left) - getheight(root->right), bff;

        if (bf > 1) {//左子树高
            //cout << "adjustBanlence= " << root->data << endl;
            bff = getheight(root->left->left) - getheight(root->left->right);//判断是ll还是lr
            if (bff >= 0) return ll_rotate(root);//高度相同也采用ll
            else return lr_rotate(root);
        }
        else if (bf < -1) {//右子树高
            //cout << "adjustBanlence= " << root->data << endl;
            bff = getheight(root->right->left) - getheight(root->right->right);
            if (bff > 0) return rl_rotate(root);
            else return rr_rotate(root);//高度相同也采用rr
        }

        return root;//不用调
    }
    BTNode* remove(BTNode* root, T e) {
        if (root == nullptr)return nullptr;//结点不存在
        if (e < root->data) {
            root->left = remove(root->left, e);//递归查找
        }
        else if (e > root->data) {
            root->right = remove(root->right, e);
        }
        else {//找到目标结点
            if (root->left == nullptr || root->right == nullptr) {//只有一棵子树
                BTNode* temp = root->right ? root->right : root->left;
                delete root;
                root = temp;
                return root;
            }
            else {//有左右子树
                BTNode* temp = getMinNode(root->right);
                root->data = temp->data;//用右子树中的最小结点代替
                root->right = remove(root->right, temp->data);//删除替代的结点
            }
        }
        //删除完马上检查
        root->height = max(getheight(root->left), getheight(root->right)) + 1;//删除操作完了,重新计算高度
        root = adjustBanlence(root);//调整
        return root;
    }
    BTNode* getMinNode(BTNode* root) {
        if (root == nullptr)return nullptr;
        while (root->left)root = root->left;
        return root;
    }
    bool is_leaf(BTNode* node) {
        if (node->left == node->right == nullptr)return true;
        else return false;
    }
    int getheight(BTNode* node) {
        if (node == nullptr)return 0;
        else return node->height;
    }
    BTNode* ll_rotate(BTNode* y) {
        if (y == nullptr) return nullptr;
        //cout << "ll_rotate= " << y->data << endl;
        BTNode* x = y->left;
        y->left = x->right;
        x->right = y;

        y->height = max(getheight(y->left), getheight(y->right)) + 1;
        x->height = max(getheight(x->left), getheight(x->right)) + 1;

        return x;
    }
    BTNode* rr_rotate(BTNode* y) {
        if (y == nullptr)return nullptr;
        //cout << "rr_rotate= " << y->data << endl;
        BTNode* x = y->right;
        y->right = x->left;
        x->left = y;

        y->height = max(getheight(y->left), getheight(y->right)) + 1;
        x->height = max(getheight(x->left), getheight(x->right)) + 1;

        return x;
    }
    BTNode* lr_rotate(BTNode* T) {
        if (T == nullptr)return nullptr;
        //cout << "lr_rotate= " << T->data << endl;
        T->left = rr_rotate(T->left);
        return ll_rotate(T);
    }
    BTNode* rl_rotate(BTNode* T) {
        if (T == nullptr)return nullptr;
        //cout << "rl_rotate= " << T->data << endl;
        T->right = ll_rotate(T->right);
        return rr_rotate(T);
    }
};
void my_inOrder(const BinTree<int>* root) {
    if (root) {
        my_inOrder(root->left);
        cout << root->data << ' ';
        my_inOrder(root->right);
    }
}
void my_preOrder(const BinTree<int>* root) {
    if (root) {
        cout << root->data << ' ';
        my_preOrder(root->left);
        my_preOrder(root->right);
    }
}
void my_floorOrder( BinTree<int>* root) {
    if (root == nullptr) return;
    queue<BinTree<int>* > q;
    q.push(root);
    int a = 1, b;
    while (!q.empty()) {
        b = 0;//记录每层有多少个结点
        for (int i = 0; i < a; i++) {
            if (q.front()->left) {
                q.push(q.front()->left); b++;
            }
            if (q.front()->right) {
                q.push(q.front()->right); b++;
            }
            cout << q.front()->data << ' ';
            q.pop();
        }
        cout << ',';
        a = b;
    }
    cout << endl;
}

void test02() {
    //sizeof(a) / sizeof(*a)
    int a3[] = { 49,38,65,97,76,13,27,49 };
    int a7[] = { 15,1,2,3,5,8,4,9,6,7 };
    int a2[] = { 1,2,3,4,5,7,8,9,10,6 };
    int a4[] = { 1,2,3,4,5,7,8,9,10,6 };
    int a6[] = { 8,3,6,4,2,1,5,7,9,10,12,11 };
    int a9[] = { 16,9,20,15,3,18,13,2,17,10,5,7,11,12,6,1,19,4,8,14 };
    int a8[] = { 53,17,78,9,45,65,87,32 };
    int a5[] = { 53, 3, 542, 748, 14, 214, 154, 63, 616 };
    int a[] = { 20,30,40,50,70,31,19,60 };

    AVL<int> avl; for (const int i : a)avl.insert(i);
    avl.remove(60);
    avl.remove(40);
    
    //avl.remove(60);
    //avl.remove(30);
    my_preOrder(avl.m_root); cout << endl;
    my_inOrder(avl.m_root); cout << endl;
    my_floorOrder(avl.m_root); cout << endl;



}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值