每日一类封装之AVL树

思路学习博客https://www.cnblogs.com/coding-nerver-die/p/10975599.html

主要是理解其中维持其平衡进行的旋转操作,分两种情况
第一种情况只需要旋转一次
在这里插入图片描述第二中情况需要先旋转下不平衡子树的子树,使其满足是一条递减的线,再旋转
在这里插入图片描述
直接上代码

template  <typename T>
struct AVLTreeNode{

    AVLTreeNode(T val,AVLTreeNode<T>* left,AVLTreeNode<T>* right)
    :val(val),left(left),right(right){}
    T val;
    int height;
    AVLTreeNode<T>* left;
    AVLTreeNode<T>* right;
    AVLTreeNode<T>* parent;
};
template <typename T>
struct AVLTree
{
public:
    AVLTree();
    ~AVLTree();

    void insert(T key); //插入
    void remove(T key); //删除某节点

    AVLTreeNode<T>* find1(AVLTreeNode<T>* pnode,T key);   //递归查找某节点
    AVLTreeNode<T>* find2(AVLTreeNode<T>* pnode,T key);   //非递归查找某节点

    int height(); //获取树的高度

    void preOrder();	//前序遍历AVL树
    void InOrder();		//中序遍历AVL树
    void postOrder();	//后序遍历AVL树

private:
    AVLTreeNode<T>* head;

    int height(AVLTreeNode<T>* pnode) ; //任意一节点的高度

    AVLTreeNode<T>* insert(AVLTreeNode<T>* &pnode, T key);
    AVLTreeNode<T>* remove(AVLTreeNode<T>* & pnode, T key);

    AVLTreeNode<T>* leftRotation(AVLTreeNode<T>* pnode);		//单旋:左旋操作
    AVLTreeNode<T>* rightRotation(AVLTreeNode<T>* pnode);		//单旋:右旋操作
    AVLTreeNode<T>* leftRightRotation(AVLTreeNode<T>* pnode);	//双旋:先左旋后右旋操作
    AVLTreeNode<T>* rightLeftRotation(AVLTreeNode<T>* pnode);	//双旋:先右旋后左旋操作
};

//构造函数
template <typename T>
AVLTree<T>::AVLTree(){
    head = NULL;
}
//销毁每个节点
template <typename  T>
AVLTree<T>::~AVLTree(){

}

template <typename T>
int AVLTree<T>::height(AVLTreeNode<T>* pnode)   //返回任一节点子树的高度
{
    if (pnode != NULL)
    {
        return pnode->height;
    }
    return 0;																//如果是空树,高度为0
};

template <typename T>
int AVLTree<T>::height()
{
    return height(head);
};

template <typename T>
AVLTreeNode<T>* AVLTree<T>::leftRotation(AVLTreeNode<T> *pnode) {
    AVLTreeNode<T>* p = pnode->right;
    pnode->right = p->left;
    p->left = pnode;

    pnode->height = max(height(pnode->left),height(pnode->right))+1;    //更新改变高度的两个节点

    p->height = height(p)+1;
}

template <typename T>
AVLTreeNode<T>* AVLTree<T>::leftRightRotation(AVLTreeNode<T>* pnode)
{
    pnode->lchild= leftRotation(pnode->lchild); //先把根节点的子树旋转一下,在旋转根节点
    return rightRotation(pnode);
}

template <typename T>
AVLTreeNode<T>* AVLTree<T>::insert(AVLTreeNode<T>* &pnode, T key){
    if(pnode== NULL){   //创建一个节点
        pnode = new AVLTreeNode<T>(key,NULL,NULL);
    }
    else if(key > pnode->val){  //如果Key大于当前根节点,就在根节点的右子树上插入
        pnode->right = insert(pnode->right,key);    //递归插入
        if(height(pnode->right) - height(pnode->left) == 2){
            if(key > pnode->right->val)
                pnode = leftRotation(pnode);
            else
                pnode = rightRotation(pnode);
        }
    }
    else if(key < pnode->val){
        pnode->left = insert(pnode->left,key);
       if(height(pnode->left) - height(pnode->right) == 2){
                if(key > pnode->left->val)
                    pnode = leftRotation(pnode);
                else
                    pnode = rightRotation(pnode);
            }
    }
    pnode->height = max(height(pnode->left), height(pnode->right)) + 1;
    return pnode;
}

template <typename T>
void AVLTree<T>::insert(T key)  //从根节点开始插入
{
    insert(head, key);
};

template <typename  T>
AVLTreeNode<T>* AVLTree<T>::find1(AVLTreeNode<T>*root,T key) {
    if(head != NULL){
        if(key == root->val)
            return root;
        else if(key > root->val)
            return find1(root->right,key);
        else
            return find1(root->left,key);
    }
}

template <typename  T>
AVLTreeNode<T>* AVLTree<T>::find2(AVLTreeNode<T>*root,T key){
    while(root != NULL){
        if(key == root->val)
            return root;
        else if(key > root->val)
           root = root->right;
        else
            root = root->left;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值