#include "MyAVLTree.h"
#include <iostream>
MyAVLTree::MyAVLTree()
{
root_ = nullptr;
}
MyAVLTree::~MyAVLTree()
{
}
void MyAVLTree::UpdateDepth(MyTNode *node)
{
if (node == nullptr)
return;
int l_depth = node->lchild == nullptr ? 0 : node->lchild->depth;
int r_depth = node->rchild == nullptr ? 0 : node->rchild->depth;
node->depth = (l_depth > r_depth ? l_depth : r_depth) + 1;
}
int MyAVLTree::GetBF(MyTNode *node)
{
int l_depth = node->lchild==nullptr?0: node->lchild->depth;
int r_depth = node->rchild == nullptr ? 0 : node->rchild->depth;
return l_depth - r_depth;
}
//左旋转本质:
//node变成其右子节点的左子节点
//node的右子节点的左子节点变成node的右子节点
MyTNode* MyAVLTree::L_Rotate(MyTNode*node)
{
//第一步 交换N和R的值
auto r_child = node->rchild;
{
auto tmp = node->value;
node->value = r_child->value;
r_child->value = tmp;
}
//第二步 N和R指针互换
{
auto tmp = r_child;
r_child = node;
node = tmp;
}
//第三步 做空N节点 r_child与r_child->r_child->r_child直连 跳过node
r_child->rchild = node->rchild;
if(node->rchild!=nullptr)
node->rchild->parent = r_child;
//第四步 node的左节点变成node的右节点
node->rchild = node->lchild;
//第五步 如果r_child拥有左节点X,node的左节点赋值为X
if (r_child->lchild != nullptr)
{
node->lchild = r_child->lchild;
r_child->lchild->parent = node;
}
//第六步 r_child左节点赋值为node
r_child->lchild = node;
node->parent = r_child;
return node;
}
MyTNode* MyAVLTree::R_Rotate(MyTNode*node)
{
//auto parent = node->parent;
auto l_child = node->lchild;
//第一步交换 node 和其左孩子的值
//这个时候node变成了原来的左孩子 左孩子l_child变成了node
//下面操作node,其实已经是新的node了,即为l_child
auto tmp = node->value;
node->value = l_child->value;
l_child->value = tmp;
{
auto tmp = node;
node = l_child;
l_child = tmp;
}
//
if (l_child->lchild != nullptr)
{
l_child->lchild = node->lchild;
if(node->lchild!=nullptr)
node->lchild->parent = l_child;
}
//
node->lchild = node->rchild;
node->rchild = l_child->rchild;
if (l_child->rchild != nullptr)
{
l_child->rchild->parent = node;
l_child->rchild = node;
}
node->parent = l_child;
l_child->rchild = node;
return node;
}
void MyAVLTree::AVLTree(MyTNode *node)
{
int bf = 0;//平衡因子
while (node != nullptr)
{
UpdateDepth(node);
bf = GetBF(node);
//说明已经不平衡了!!!!
if (bf > 1 || bf < -1)
{
//左子树高
if (bf > 1)
{
int l_bf = GetBF(node->lchild);
if (l_bf > 0)//LL型
{
//需要重新计算深度
node = R_Rotate(node);
continue;
}
else//LR型
{
node = L_Rotate(node->lchild);
//R_Rotate(node);
//node = tmp;
continue;
}
}
if (bf < -1)
{
int l_bf = GetBF(node->rchild);
if (l_bf <0)//RR型
{
//需要重新计算深度
node = L_Rotate(node);
continue;
}
else//RL型
{
//需要重新计算深度
node = R_Rotate(node->rchild);
continue;
}
}
//需要调整
}
node = node->parent;
}
}
void MyAVLTree::Insert(int val)
{
//返回插入节点所在位置,按二叉排序树的简单插入
MyTNode* node = InsertVal(root_, root_, val);
//更新深度
UpdateDepth(node);
//二叉树的平衡调整,里面会递归更新每个节点的深度
AVLTree(node);
}
void MyAVLTree::PrintLastOrder(MyTNode *node)
{
if (node == nullptr)
return;
PrintLastOrder(node->lchild);
PrintLastOrder(node->rchild);
std::cout << node->value << std::endl;
}
void MyAVLTree::PrintMidOrder(MyTNode *node)
{
if (node == nullptr)
return;
std::cout << node->value << std::endl;
PrintMidOrder(node->lchild);
PrintMidOrder(node->rchild);
}
void MyAVLTree::PrintPreOrder(MyTNode *node)
{
if (node == nullptr)
return;
PrintPreOrder(node->lchild);
std::cout << node->value << std::endl;
PrintPreOrder(node->rchild);
}
MyTNode* MyAVLTree::InsertVal(MyTNode* &node, MyTNode* &parent, int val)
{
if(node == nullptr)
{
if (parent == nullptr)
{
node = new MyTNode();
node->value = val;
node->parent = nullptr;
return node;
}
node = new MyTNode();
node->value = val;
node->parent = parent;
return node;
}
if (node->value > val)
{
return InsertVal(node->lchild, node, val);
}
else
{
return InsertVal(node->rchild, node, val);
}
}
重点:
原文:https://www.cnblogs.com/shawnc24/p/10449280.html