数据结构(十)二叉平衡树

本文详细介绍了AVL树的概念,包括其定义和性质,并提供了C++实现AVL树的模板类,包括节点定义、插入、删除、旋转等关键操作。通过这些操作,确保了AVL树在插入和删除后仍保持平衡,从而保持高效的查找性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉平衡树–c++实现

AVL树

定义:一颗空的二叉树是AVL树;如果T是一颗非空的二叉树, T L 和 T R T_L和T_R TLTRf分别是其左子树和右子树,那么当T满足以下条件时,T是一颗AVL树:

  1. T L 和 T R T_L和T_R TLTR是AVL树

  2. ∣ h L − h R ∣ ≤ 1 |h_L - h_R| \le 1 hLhR1,其中 h L 和 h R 分别是 T L 和 T R h_L和h_R分别是T_L和T_R hLhR分别是TLTR的高.

一颗AVL搜索树既是二叉搜索树,也是AVL树。

AVL树的描述

template<class K,class E> struct AVLNode{
    K key;
    E value;
    AVLNode<K,E> *leftChild,*rightChild;
    int height;
    AVLNode(){
        leftChild = rightChild = nullptr;
        height = 0;
    }
    AVLNode(K theKey,E theValue){
        key = theKey;
        value = theValue;
        leftChild = rightChild = nullptr;
        height = 1;
    }
};
template<class K, class E>
class AVLTree {
private:
    AVLNode<K,E> *root;
    AVLNode<K,E>* leftRotation(AVLNode<K,E>* proot); // 单左旋
    AVLNode<K,E>* rightRotation(AVLNode<K,E>* proot);// 右单旋
    AVLNode<K,E>* rightLeftRotation(AVLNode<K,E>* proot);//先右旋再左旋
    AVLNode<K,E>* leftRightRotation(AVLNode<K,E>* proot);//先左旋再右旋
    int height(AVLNode<K,E>* proot);
public:
    AVLTree();
    ~AVLTree();
    int getSize() const;
    AVLNode<K,E>* find(K theKey) const;
    void insert(K theKey, E theValue);
    void del(K theKey);
};

AVL树的实现

#include "AVLTree.h"
#include <algorithm>

using namespace std;

template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::leftRotation(AVLNode<K, E> *proot) {
    AVLNode<K, E> *prchild = proot->rightChild;
    proot->rightChild = prchild->leftChild;
    prchild->leftChild = proot;

    proot->height = max(proot->leftChild->height, proot->rightChild->height) + 1;     //更新节点的高度值
    prchild->height = max(prchild->leftChild->height, prchild->rightChild->height) + 1; //更新节点的高度值
    return prchild;
}

template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::rightRotation(AVLNode<K, E> *proot) {
    AVLNode<K, E> *plchild = proot->leftChild;
    proot->leftChild = plchild->rightChild;
    plchild->rightChild = proot;

    proot->height = max(proot->leftChild->height, proot->rightChild->height) + 1;
    plchild->height = max(plchild->leftChild->height, plchild->rightChild->height) + 1;

    return plchild;
}

template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::rightLeftRotation(AVLNode<K, E> *proot) {
    proot->rightChild = rightRotation(proot->rightChild);
    return leftRotation(proot);
}

template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::leftRightRotation(AVLNode<K, E> *proot) {
    proot->leftChild = leftRotation(proot->leftChild);
    return rightRotation(proot);
}

template<class K, class E>
int AVLTree<K, E>::height(AVLNode<K, E> *proot) {
    if (proot == nullptr) return 0;
    else {
        int lefth = height(proot->leftChild);
        int righth = height(proot->rightChild);
        return max(lefth, righth) + 1;
    }
}


template<class K, class E>
AVLTree<K, E>::AVLTree() {
    root = nullptr;

}

template<class K, class E>
AVLTree<K, E>::~AVLTree() {

}

template<class K, class E>
int AVLTree<K, E>::getSize() const {
    return 1;
}

template<class K, class E>
AVLNode<K, E> *AVLTree<K, E>::find(K theKey) const {
    AVLNode<K, E> *p = root;
    while (p->key != theKey) {
        if (p->key > theKey) p = p->leftChild;
        else p = p->rightChild;
    }
    return p;
}

template<class K, class E>
void AVLTree<K, E>::insert(K theKey, E theValue) {
    if (root == nullptr) {
        root = new AVLNode<K, E>(theKey, theValue);
        root->height = 1;
        return;
    }
    AVLNode<K, E> *p = root;
    AVLNode<K, E> *pr = nullptr; //p的双亲
    AVLNode<K, E> *prp = nullptr;//prp的双亲
    while (p != nullptr) {
        prp = pr;
        pr = p;
        if (theKey > p->key) {
            p = p->rightChild;
        } else {
            p = p->leftChild;
        }
    }
    if (pr->key > theKey) pr->leftChild = new AVLNode<K, E>(theKey, theValue);
    else pr->rightChild = new AVLNode<K, E>(theKey, theValue);
    if (prp == nullptr) return;
    if (height(prp->rightChild) - height(prp->leftChild) == 2) {
        if (theKey > pr->key) prp = leftRotation(prp);
        else if (theKey < pr->key) prp = rightLeftRotation(prp);

        return;
    } else if (height(prp->leftChild) - height(prp->rightChild) == 2) {
        if (theKey > pr->key) prp = rightRotation(prp);
        else if (theKey < pr->key) prp = leftRightRotation(prp);

        return;
    }

}

template<class K, class E>
void AVLTree<K, E>::del(K theKey) { //删除节点时,如果节点同时拥有左子树和右子树,
                                // 则在高度高的子树上选择最大(或最小)元素进行替换,这样能保证替换后不会再出现失衡的现
    AVLNode<K, E> *p = root,
            *pp = nullptr,
            *ppp = nullptr;
    while (p->key != theKey) {
        ppp = pp;
        pp = p;
        if (theKey > p->key) p = p->rightChild;
        else p = p->leftChild;
    }
    if (p->leftChild != nullptr && p->rightChild != nullptr) {
        if (height(p->leftChild) > height(p->rightChild)) {
            AVLNode<K, E> *pl = p->leftChild, *plp = p;
            while (pl->rightChild != nullptr) {
                plp = pl;
                pl = pl->rightChild;
            }
            K k = pl->key;
            E v = pl->value;
            del(k);
            p->key = k;
            p->value = v;
            plp->rightChild = nullptr;
        } else {
            AVLNode<K, E> *pl = p->rightChild, *plp = p;
            while (pl->leftChild != nullptr) {
                p = pl;
                pl = pl->leftChild;
            }
            K k = pl->key;
            E v = pl->value;
            del(k);
            p->key = k;
            p->value = v;
            plp->leftChild = nullptr;
        }
    } else if (p->leftChild == nullptr && p->rightChild == nullptr) {
        if (theKey > pp->key) {
            delete p;
            pp->rightChild = nullptr;
            if (height(pp->leftChild) - height(pp->rightChild) == 2) {
                if (pp->leftChild->leftChild != nullptr) {
                    ppp = rightRotation(ppp);
                    return;
                } else {
                    ppp = leftRightRotation(ppp);
                    return;
                }
            }
        }
        else if (theKey < pp->key)
            delete p;
        pp->leftChild = nullptr;
        if (height(pp->rightChild) - height(pp->leftChild) == 2){
            if (pp->rightChild->rightChild != nullptr){
                ppp = leftRotation(ppp);
                return;
            } else{
                ppp = rightLeftRotation(ppp);
                return;
            }
        }
    }else{
        if (theKey > pp->key) {
            pp->rightChild = p->leftChild != nullptr ? p->leftChild:p->rightChild;
            delete p;
        } else{
            pp->leftChild = p->leftChild != nullptr ? p->leftChild:p->rightChild;
            delete p;
        }
    }

}

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值