AVL树C++实现

说来惭愧,工作三年了一直都没有真正弄懂AVL树的原理。因为最近在看STL源码,但STL的map和set的底层数据结构是红黑树,而红黑树是不严格的AVL树,所以理解红黑树之前必须要先弄懂AVL树。借此契机,将AVL树从原理和代码层面拿下。

1. AVL树简介

AVL树种的任意节点的左右子树的高度差的绝对值最大为1,其本质是带了平衡功能的二叉搜索树

二叉搜索树在数据极端情况下会退化成单链表,时间复杂度也会退化成O(n)。而AVL树定义了旋转操作,在平衡因子大于2时,通过旋转来调整树的结构,来重新满足平衡因子小于2,确保在查找、插入和删除在平均和最坏情况下都是O(logn)。

2. AVL旋转

AVL旋转是AVL树最核心的部分,需要重点掌握。在理解AVL旋转之前先知道以下几个概念:

  • AVL树节点的插入总是在叶子节点;
  • AVL树在插入节点之前是满足平衡条件的;
  • 插入新节点后有可能满足平衡条件也可能不满足;
  • 当不满足平衡条件时需要对新的树进行旋转。

旋转之前首先需要找到插入节点向上第一个不平衡的节点(记为A),新插入节点只能在A的的左子树的左子树、左子树的右子树、右子树的左子树、右子树的右子树上,对应四种不同的旋转方式。

 

#ifndef _AVLTREE_H
#define _AVLTREE_H

#include <iostream>


template<typename T>
class AVLNode {
public:
    T val;
    AVLNode* left;
    AVLNode* right;
    AVLNode(T x) :val(x), left(NULL), right(NULL) {}
};


template<typename T>
class AVLTree {
    typedef AVLNode<T> AVLNode;
private:
    AVLNode* avlroot;

    int max(int a, int b) {
        return a > b ? a : b;
    }

    //获取树高度
    int treeHeight(const AVLNode* root) {
        if (root == NULL)
            return 0;
        return max(treeHeight(root->left), treeHeight(root->right)) + 1;
    }

    //计算平衡因子
    int treeBalanceFector(const AVLNode* root) {
        if (root == NULL)
            return 0;
        return treeHeight(root->left) - treeHeight(root->right);
    }

    //向左旋转
    AVLNode* rotateLeft(AVLNode* root) {
        AVLNode* tmp = root->right;
        root->right = tmp->left;
        tmp->left = root;
        return tmp;
    }

    //向右旋转
    AVLNode* rotateRight(AVLNode* &root) {
        AVLNode* tmp = root->left;
        root->left = tmp->right;
        tmp->right = root;
        return tmp;
    }

    //获取最小节点
    AVLNode* minNode(AVLNode* root) {
        if (root->left != NULL)
            root = root->left;
        return root;
    }

    //重新平衡
    AVLNode* treeRebalance(AVLNode* root) {

        int fector = treeBalanceFector(root);

        if (fector > 1 && treeBalanceFector(root->left) > 0)  // LL
            return rotateRight(root);

        if (fector > 1 && treeBalanceFector(root->left) <= 0) // LR
        {
            root->left = rotateLeft(root->left);
            return rotateRight(root);
        }

        if (fector < -1 && treeBalanceFector(root->right) <= 0) // RR
            return rotateLeft(root);

        if (fector < -1 && treeBalanceFector(root->right) > 0)  // RL
        {
            root->right = rotateRight(root->right);
            return rotateLeft(root);
        }

        return root;
    }

    //插入节点
    void treeInsert(AVLNode*& root, const T& val) {

        if (root == NULL) {
            root = new AVLNode(val);
        }
        else {
            if (val == root->val)
                return;
            if (val < root->val)
                treeInsert(root->left, val);
            else
                treeInsert(root->right, val);
        }
        root = treeRebalance(root);
    }

    //删除节点
    void treeDelete(AVLNode*& root, const T& val) {

        if (root == NULL)
            return;

        if (val == root->val) {
            if (root->right != NULL){
                AVLNode* min_node = minNode(root->right);
                root->val = min_node->val;
                delete min_node;
            }
            else {
                AVLNode* deleteNode = root;
                root = root->left;
                delete deleteNode;
            }
        }
        else {
            if (val < root->val)
                treeDelete(root->left, val);
            else
                treeDelete(root->right, val);
        }

        root = treeRebalance(root);
    }

    //前序遍历
    void preOrderTraversal(AVLNode* root) {
        if (root == NULL)
            return;
        std::cout << root->val << " ";
        preOrderTraversal(root->left);
        preOrderTraversal(root->right);
    }

    //中序遍历
    void midOrderTraversal(AVLNode* root) {
        if (root == NULL)
            return;
        midOrderTraversal(root->left);
        std::cout << root->val << " ";
        midOrderTraversal(root->right);
    }

public:

    AVLTree() {
        avlroot = NULL;
    }

    ~AVLTree() {
    
    }

    void insert(const T& val) {
        treeInsert(avlroot, val);
    }

    void del(const T& val) {
        treeDelete(avlroot, val);
    }

    void preOrder() {
        preOrderTraversal(avlroot);
    }

    void midOrder() {
        midOrderTraversal(avlroot);
    }
};


#endif // !_AVLTREE_H

 

转载于:https://www.cnblogs.com/evenleee/p/11218478.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值