平衡二叉樹-的四種旋轉調整(代碼,圖解)
1.右單旋:
新插入節點插入在較高左子樹的左側(左左右),插入新節點二十:
1.修改parent和curLR的孩子指針域
parent->left = curLR;
// 避免左單支的場景:subLR是nullptr
if (subLR)
curLR->parent = parent;
2.修改parent和curL的指針域
curL->right = parent;
3.處理旋轉之前parent的雙親的孩子
// 因爲parent可能是某個節點的子樹,因此在更新parent的雙親前必須先將其之前的雙親記錄
Node* pparent = parent->parent;
parent->parent = curL;
curL->parent = pparent;
// parent可能是根節點:需要修改_root
// parent也可能是一棵子樹: 需要修改pparent的左/右指針域的指向
if (nullptr == pparent)
{
// 旋轉之前parent是根節點
_root = subL;
}
else
{
// parent是某個節點的子樹
if (parent == pparent->left)
pparent->left = curL;
else
pparent->right = curL;
}
2.左單旋
新插入節點插入在較高右子樹的右側(右右左),插入新節點60
同理右單旋:
void RotateLeft(Node* parent)
{
Node* subR = parent->right;
Node* subRL = subR->left;
parent->right = subRL;
// 避免:右單支
if (subRL)
subRL->parent = parent;
subR->left = parent;
// 需要更新parent和subR的雙親
Node* pparent = parent->parent;
parent->parent = subR;
subR->parent = pparent;
// 旋轉之前:
// parent可能是根節點:修改_root的指向
// parent可能是子樹:修改原parent左||右指針域的指向
if (nullptr == pparent)
{
_root = subR;
}
else
{
if (parent == pparent->left)
pparent->left = subR;
else
pparent->right = subR;
}
}
3.左右雙旋
新插入節點插入在較高左子樹的右側,先左旋調整爲需要右旋的情況,再右旋
void RotateLR(Node* parent)
{
RotateLeft(parent->left);
RotateRight(parent);
}
4.右左雙旋
新插入節點插入在較高右子樹的左側,先右旋調整爲需要左旋的情況,再左旋
void RotateRL(Node* parent)
{
RotateRight(parent->right);
RotateLeft(parent);
}