在旋转后更新AVL树中的平衡因子-我做错了什么? 我在C++中实现了AVL树,熟悉单轮和双轮的概念。通过计算balance\u factor=height(left\u child)-height(right\u child),以及尝试通过存储其平衡因子并将其保持在[-1,1]范围内来实现更高效的AVL树,我成功地实现了该树。请注意,在尝试删除基于失衡因子的数据之前,我目前只查看插入

在旋转后更新AVL树中的平衡因子-我做错了什么? 我在C++中实现了AVL树,熟悉单轮和双轮的概念。通过计算balance\u factor=height(left\u child)-height(right\u child),以及尝试通过存储其平衡因子并将其保持在[-1,1]范围内来实现更高效的AVL树,我成功地实现了该树。请注意,在尝试删除基于失衡因子的数据之前,我目前只查看插入,c++,data-structures,tree,avl-tree,C++,Data Structures,Tree,Avl Tree,本质上,用于插入的伪代码如下所示: 找到插入节点的正确位置,将访问的每个节点从根节点推到堆栈中 每次更新堆栈中所有节点的平衡因子一个,但如果在过程中将平衡因子调整为0,则停止更新 使用堆栈,在保持balance_factor为-2或2的节点上递归地平衡树 到目前为止,该算法似乎或多或少适用于某些值集,但在某些情况下不起作用。 查看字符串的AVL树,我的算法在到达其平衡因子更新为0的节点时停止传播。在底部情况下,平衡因子的更新在1[0]处停止,根节点fad[-1]的平衡因子不会更新为0,尽管其

本质上,用于插入的伪代码如下所示:

  • 找到插入节点的正确位置,将访问的每个节点从根节点推到堆栈中
  • 每次更新堆栈中所有节点的平衡因子一个,但如果在过程中将平衡因子调整为0,则停止更新
  • 使用堆栈,在保持
    balance_factor
    为-2或2的节点上递归地平衡树
  • 到目前为止,该算法似乎或多或少适用于某些值集,但在某些情况下不起作用。

    查看字符串的AVL树,我的算法在到达其
    平衡因子更新为0的节点时停止传播。在底部情况下,平衡因子的更新在
    1[0]
    处停止,根节点
    fad[-1]
    的平衡因子不会更新为0,尽管其子树共享相同的最大高度

    AVL树上的wiki页面提到:

    如果平衡因子变为0意味着该子树的高度保持不变,则可以停止回溯

    但是,我不明白为什么在LR/RL旋转可能需要将
    平衡因子
    值的更新传播到该节点之外时会出现这种情况

    TL;医生:我在做一些概念上错误的事情吗?

    插入

    template <typename T>
    void AVLTree<T>::insert(const T& value)
    {
        std::stack<BinTree> path_nodes;
        insert_in_node(BSTree<T>::get_root(), value, path_nodes);
    }
    
    template <typename T>
    void AVLTree<T>::insert_in_node(BinTree& node, const T& value,
        std::stack<BinTree>& path_nodes)
    {
        if (!node)
        {
            node = BSTree<T>::make_node(value);
            update_balance_factors(path_nodes, value, true);
            balance(path_nodes);
        }
        else
        {
            ++node->count;
            path_nodes.push(node);
    
            if (value < node->data)
                insert_in_node(node->left, value, path_nodes);
            else if (value > node->data)
                insert_in_node(node->right, value, path_nodes);
        }
    }
    
    模板
    void AVLTree::insert(常量和值)
    {
    std::堆栈路径_节点;
    在_节点中插入_(BSTree::get_root(),value,path_节点);
    }
    模板
    void AVLTree::在节点中插入节点(BinTree&node,const T&value,
    std::堆栈和路径(U节点)
    {
    如果(!节点)
    {
    node=BSTree::make_节点(值);
    更新平衡因子(路径节点,值,真);
    平衡(路径节点);
    }
    其他的
    {
    ++节点->计数;
    路径\节点。推送(节点);
    if(值<节点->数据)
    在_节点中插入_(节点->左,值,路径_节点);
    else if(值>节点->数据)
    在_节点中插入_(节点->右侧,值,路径_节点);
    }
    }
    
    平衡/更新平衡因子值

    template <typename T>
    void AVLTree<T>::balance(std::stack<BinTree>& path_nodes)
    {
        while (!path_nodes.empty())
        {
            BinTree tree = path_nodes.top();
            path_nodes.pop();
    
            int balanceFactor = tree->balance_factor;
    
            if (balanceFactor < -1 || balanceFactor > 1)
            {
                // there is a need to rotate and balance
                if (balanceFactor > 0)
                {
                    // left side is deeper than right side
                    if (tree->left->balance_factor > 0)
                    {
                        // LL
                        rotate_right(tree);
                    }
                    else
                    {
                        // LR
                        rotate_left(tree->left);
                        rotate_right(tree);
                    }
                }
                else
                {
                    // right side is deeper than left side
                    if (tree->right->balance_factor < 0)
                    {
                        // RR
                        rotate_left(tree);
                    }
                    else
                    {
                        // RL
                        rotate_right(tree->right);
                        rotate_left(tree);
                    }
                }
    
                reparent(path_nodes, tree);
                update_balance_factors(path_nodes, tree->data, false);
            }
        }
    }
    
    template <typename T>
    void AVLTree<T>::update_balance_factors(std::stack<BinTree> path_nodes,
        const T& value, bool inserting)
    {
        while (!path_nodes.empty())
        {
            BinTree parent = path_nodes.top();
            path_nodes.pop();
    
            if (value < parent->data)
            {
                // value belongs to the left subtree
                if (inserting)
                    ++parent->balance_factor;
                else
                    --parent->balance_factor;
            }
            else
            {
                // value belongs to the right subtree
                if (inserting)
                    --parent->balance_factor;
                else
                    ++parent->balance_factor;
            }
    
            // break out of loop if balance factor is adjusted to 0
            if (!parent->balance_factor)
                break;
        }
    }
    
    模板
    void AVLTree::balance(标准::堆栈和路径节点)
    {
    而(!path_nodes.empty())
    {
    BinTree-tree=path_nodes.top();
    path_nodes.pop();
    int balanceFactor=树->平衡因子;
    如果(平衡因子<-1 | |平衡因子>1)
    {
    //需要旋转和平衡
    如果(平衡系数>0)
    {
    //左侧比右侧深
    如果(树->左->平衡系数>0)
    {
    //LL
    向右旋转(树);
    }
    其他的
    {
    //LR
    向左旋转(树->左);
    向右旋转(树);
    }
    }
    其他的
    {
    //右侧比左侧深
    如果(树->右->平衡系数<0)
    {
    //RR
    向左旋转(树);
    }
    其他的
    {
    //RL
    向右旋转(树->右);
    向左旋转(树);
    }
    }
    重新分配(路径\节点,树);
    更新平衡因子(路径节点,树->数据,false);
    }
    }
    }
    模板
    void AVLTree::更新\平衡\因子(标准::堆栈路径\节点,
    常量T和值,布尔插入)
    {
    而(!path_nodes.empty())
    {
    BinTree parent=path_nodes.top();
    path_nodes.pop();
    如果(值<父项->数据)
    {
    //值属于左子树
    如果(插入)
    ++父项->平衡系数;
    其他的
    --父项->平衡系数;
    }
    其他的
    {
    //值属于右子树
    如果(插入)
    --父项->平衡系数;
    其他的
    ++父项->平衡系数;
    }
    //如果平衡系数调整为0,则断开回路
    如果(!父项->平衡系数)
    打破
    }
    }
    
    旋转/重新租赁

    template <typename T>
    void AVLTree<T>::rotate_left(BinTree& pivot)
    {
        BinTree temp = pivot;
        pivot = pivot->right;
        temp->right = pivot->left;
        pivot->left = temp;
    
        temp->count -= ((pivot->right) ? pivot->right->count : 0) + 1;
        pivot->count += ((temp->left) ? temp->left->count : 0) + 1;
    
        temp->balance_factor += 1
            - ((pivot->balance_factor < 0) ? pivot->balance_factor : 0);
    
        pivot->balance_factor += 1
            + ((0 < temp->balance_factor) ? temp->balance_factor : 0);
    }
    
    template <typename T>
    void AVLTree<T>::rotate_right(BinTree& pivot)
    {
        BinTree temp = pivot;
        pivot = pivot->left;
        temp->left = pivot->right;
        pivot->right = temp;
    
        temp->count -= ((pivot->left) ? pivot->left->count : 0) + 1;
        pivot->count += ((temp->right) ? temp->right->count : 0) + 1;
    
        temp->balance_factor -= 1
            + ((pivot->balance_factor > 0) ? pivot->balance_factor : 0);
    
        pivot->balance_factor -= 1
            - ((0 > temp->balance_factor) ? temp->balance_factor : 0);
    }
    
    template <typename T>
    void AVLTree<T>::reparent(std::stack<BinTree>& path_nodes,
        const BinTree& orphan)
    {
        if (path_nodes.empty())
        {
            BSTree<T>::get_root() = orphan;
        }
        else
        {
            BinTree parent = path_nodes.top();
            if (parent->data < orphan->data)
                parent->right = orphan;
            else
                parent->left = orphan;
        }
    }
    
    模板
    void AVLTree::向左旋转(BinTree和pivot)
    {
    二叉树温度=枢轴;
    枢轴=枢轴->右侧;
    温度->右=枢轴->左;
    枢轴->左=温度;
    临时->计数-=((枢轴->右)?枢轴->右->计数:0)+1;
    枢轴->计数+=((临时->左)?临时->左->计数:0)+1;
    温度->平衡系数+=1
    -((枢轴->平衡系数<0)?枢轴->平衡系数:0);
    枢轴->平衡系数+=1
    +((0<温度>平衡系数)?温度>平衡系数:0);
    }
    模板
    void AVLTree::向右旋转(BinTree和pivot)
    {
    二叉树温度=枢轴;
    枢轴=枢轴->左;
    温度->左=枢轴->右;
    枢轴->右侧=温度;
    临时->计数-=((枢轴->左)?枢轴->左->计数:0)+1;
    透视->计数+=((临时->右侧)?临时->右侧->计数:0)+1;
    温度->平衡系数-=1
    +((枢轴->平衡系数>0)?枢轴->平衡系数:0);
    枢轴->平衡系数-=1
    -((0>温度->平衡系数)?温度->平衡系数:0);
    }
    模板
    void AVLTree::repart(标准::堆栈和路径_节点,
    康斯特·宾特里(孤儿)
    {
    if(path_nodes.em