当前位置: 首页 > article >正文

高级数据结构02AVL树

文章目录

    • 1.数据结构实现
    • 2.代码说明
      • 2.1. 插入操作:
      • 2. 2删除操作:
      • 2.3.平衡检查:
      • 2.4. 中序遍历:

1.数据结构实现

#include <iostream>
using namespace std;

template<typename T>
class AVL {
public:
    AVL() { _root = nullptr; }

    // 递归实现AVL树的插入操作  BST + 平衡
    void insert(const T &val) {
        _root = _insert(_root, val);
    }

    // 递归实现AVL树的删除操作  BST + 平衡
    void remove(const T &val) {
        _root = _remove(_root, val);
    }

    // 判断一颗二叉搜索树是不是平衡树,是返回true,否则返回false
    bool isAVL() {
        return _isAVL(_root);
    }

    // 中序遍历
    void inorder() {
        _inorder(_root);
        cout << endl;
    }

private:
    struct AVLNode {
        AVLNode(T data = T())
            : _data(data), _left(nullptr), _right(nullptr), _height(1) {}
        T _data;
        AVLNode *_left;
        AVLNode *_right;
        int _height; // 存储的就是节点的高度
    };

    // 返回节点的高度
    int height(AVLNode *node) const {
        return node == nullptr ? 0 : node->_height;
    }

    // 返回左右子树最高的层数
    int maxHeight(AVLNode *node1, AVLNode *node2) {
        return height(node1) > height(node2) ? height(node1) : height(node2);
    }

    // 左旋转操作 以node为根节点进行左旋转,返回旋转后的根节点
    AVLNode* leftRotate(AVLNode *node) {
        AVLNode *child = node->_right;
        node->_right = child->_left;
        child->_left = node;
        node->_height = maxHeight(node->_left, node->_right) + 1;
        child->_height = maxHeight(child->_left, child->_right) + 1;
        return child;
    }

    // 右旋转操作
    AVLNode* rightRotate(AVLNode *node) {
        AVLNode *child = node->_left;
        node->_left = child->_right;
        child->_right = node;
        node->_height = maxHeight(node->_left, node->_right) + 1;
        child->_height = maxHeight(child->_left, child->_right) + 1;
        return child;
    }

    // 左平衡  左-右旋转
    AVLNode* leftBalance(AVLNode *node) {
        leftRotate(node->_left);
        return rightRotate(node);
    }

    // 右平衡  右-左旋转
    AVLNode* rightBalance(AVLNode *node) {
        rightRotate(node->_right);
        return leftRotate(node);
    }

    // 插入辅助函数
    AVLNode* _insert(AVLNode* node, const T& val) {
        if (node == nullptr) {
            return new AVLNode(val);
        }
        if (val < node->_data) {
            node->_left = _insert(node->_left, val);
        } else if (val > node->_data) {
            node->_right = _insert(node->_right, val);
        } else {
            return node; // 不允许插入重复值
        }

        node->_height = maxHeight(node->_left, node->_right) + 1;

        int balance = height(node->_left) - height(node->_right);
        if (balance > 1) { // 左重
            if (val < node->_left->_data) {
                return rightRotate(node); // 左左
            } else {
                return leftBalance(node); // 左右
            }
        } else if (balance < -1) { // 右重
            if (val > node->_right->_data) {
                return leftRotate(node); // 右右
            } else {
                return rightBalance(node); // 右左
            }
        }
        return node;
    }

    // 删除辅助函数
    AVLNode* _remove(AVLNode* node, const T& val) {
        if (node == nullptr) {
            return node;
        }
        if (val < node->_data) {
            node->_left = _remove(node->_left, val);
        } else if (val > node->_data) {
            node->_right = _remove(node->_right, val);
        } else {
            if (node->_left == nullptr || node->_right == nullptr) {
                AVLNode* temp = node->_left ? node->_left : node->_right;
                if (temp == nullptr) {
                    temp = node;
                    node = nullptr;
                } else {
                    *node = *temp;
                }
                delete temp;
            } else {
                AVLNode* temp = node->_right;
                while (temp->_left != nullptr) {
                    temp = temp->_left;
                }
                node->_data = temp->_data;
                node->_right = _remove(node->_right, temp->_data);
            }
        }

        if (node == nullptr) {
            return node;
        }

        node->_height = maxHeight(node->_left, node->_right) + 1;

        int balance = height(node->_left) - height(node->_right);
        if (balance > 1) { // 左重
            if (height(node->_left->_left) >= height(node->_left->_right)) {
                return rightRotate(node); // 左左
            } else {
                return leftBalance(node); // 左右
            }
        } else if (balance < -1) { // 右重
            if (height(node->_right->_right) >= height(node->_right->_left)) {
                return leftRotate(node); // 右右
            } else {
                return rightBalance(node); // 右左
            }
        }
        return node;
    }

    // 判断是否平衡辅助函数
    bool _isAVL(AVLNode* node) {
        if (node == nullptr) {
            return true;
        }
        int balance = height(node->_left) - height(node->_right);
        if (abs(balance) > 1) {
            return false;
        }
        return _isAVL(node->_left) && _isAVL(node->_right);
    }

    // 中序遍历辅助函数
    void _inorder(AVLNode* node) {
        if (node == nullptr) {
            return;
        }
        _inorder(node->_left);
        cout << node->_data << " ";
        _inorder(node->_right);
    }

    AVLNode *_root;
};

int main() {
    AVL<int> tree;
    tree.insert(10);
    tree.insert(20);
    tree.insert(30);
    tree.insert(40);
    tree.insert(50);
    tree.insert(25);

    cout << "Inorder traversal of the constructed AVL tree is \n";
    tree.inorder();

    tree.remove(30);
    cout << "\nInorder traversal after deletion of 30 \n";
    tree.inorder();

    return 0;
}

2.代码说明

2.1. 插入操作:

• 使用递归的方式将新值插入到合适的位置。
• 插入后,更新节点的高度,并检查是否需要旋转来保持平衡。
• 根据失衡的类型(左左、左右、右右、右左),进行相应的旋转操作。

2. 2删除操作:

• 使用递归的方式找到要删除的节点。
• 删除后,更新节点的高度,并检查是否需要旋转来保持平衡。
• 同样根据失衡的类型进行旋转操作。

2.3.平衡检查:

• 通过计算每个节点的平衡因子来判断是否平衡。
. • 如果平衡因子的绝对值大于1,则说明树不平衡。

2.4. 中序遍历:

• 使用递归的方式进行中序遍历,输出树中的所有节点。
测试在 main 函数中,插入了一些节点并进行了删除操作,最后输出了中序遍历的结果,可以用来验证AVL树的正确性。


http://www.kler.cn/a/611910.html

相关文章:

  • AI编程工具哪家强?对比Cusor、Copilot、Cline
  • C++算法深度解析:快速排序的实现、分析与优化
  • RoMA: 基于Mamba的遥感基础模型, 已开源, 首次验证mamba的scaling能力
  • 用数组遍历出来的页面,随节点创建的ref存储在数据仓库中,如果数据删除,页面相关节点也会删除,数据仓库中随节点创建的ref会不会也同时删除
  • STM32F103C8T6移植DMP解算MPU6050
  • Elasticsearch:使用 Azure AI 文档智能解析 PDF 文本和表格数据
  • linux---------进程概念(完)
  • 字节真题,问a,b,c指的地址是否相同?
  • SQL Server常见问题解析
  • 记录react和vue 属性传组件相关的事宜
  • 微软重磅发布 OmniParser V2.0:AI 视觉解析能力跃升,开启界面自动化新时代
  • 鸿蒙Flutter实战:20. Flutter集成高德地图,同层渲染
  • AG7220替代方案|ASL6328芯片设计|HDMI2.0 Retimer中继器方案
  • 核函数(机器学习深度学习)
  • win11+ubuntu双系统安装
  • 【解决】Linux命令报错:Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64
  • Python爬虫:Asyncpy 的详细使用和案例(高性能异步爬虫框架)
  • 安装node,配置npm, yarn, pnpm, bun
  • [Synth 8-439] module ‘xpm_fifo_async‘ not found
  • xr-frame 用cube代替线段实现两点间的连线