在旋转后更新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,尽管其
balance_factor
为-2或2的节点上递归地平衡树平衡因子更新为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