Я пытаюсь реализовать дерево AVL. Существует функция добавления узла для добавления узлов в дерево, которая в дальнейшем вызывает функцию ребалансировки, чтобы проверить коэффициент баланса добавляемых узлов. Функция добавления работает правильно, но не происходит перестановки узлов, даже если коэффициент баланса выходит за пределы диапазона [-1,1]. Обход порядка уровней возвращает одно и то же дерево каждый раз даже после добавления узлов.
template<class T>
class avl{
private:
Node<T>* root;
//REBALANCE FUNCTION
Node<T>* rebalance(Node<T>* &node){
int bal_fact=balance_factor(node);
if(bal_fact>1){
if(balance_factor(node->m_left)>0){
node=ll_rotate(node);
}else{
node=lr_rotate(node);
}
}
if(bal_fact<-1){
if(balance_factor(node->m_right)>0){
node=rl_rotate(node);
}else{
node=rr_rotate(node);
}
}
return node;
}
//HEIGHT FUNCTION
int height(Node<T>* node){
if(node==nullptr){return 0;}
int l_height=height(node->m_left);
int r_height=height(node->m_right);
if(l_height>=r_height){return l_height+1;}
else{return r_height+1;}
}
//balance_factor
int balance_factor(Node<T>* node){
int l_height= height(node->m_left);
int r_height= height(node->m_right);
int diff= (l_height-(r_height));
return diff;
}
//LL Rotation(Left Rotation)
//when the imbalance factor is caused in the right child's right subtree
Node<T>* ll_rotate(Node<T>* &grand_parent_node){
Node<T>* temp = grand_parent_node->m_right;
grand_parent_node->m_right=temp->m_left;
temp->m_left=grand_parent_node;
return temp;
}
//RR Rotate
//when the imabalance is caused in the left childs left subtree
Node<T>* rr_rotate(Node<T>* &grand_parent_node){
Node<T>* temp= grand_parent_node->m_left;
grand_parent_node->m_left=temp->m_right;
temp->m_right=grand_parent_node;
return temp;
}
//RL Rotate[Right left Rotation]
//when the imbalance is in the right child's left subtree
Node<T>* rl_rotate(Node<T>* &grand_parent_node){
grand_parent_node->m_right=rr_rotate(grand_parent_node->m_right);
return ll_rotate(grand_parent_node);
}
//Lr Rotate[Left right Rotation]
//when the imbalance is in the left child's right subtree
Node<T>* lr_rotate(Node<T>* &grand_parent_node){
grand_parent_node->m_left=ll_rotate(grand_parent_node->m_left);
return rr_rotate(grand_parent_node);
}
public:
avl(){
root=nullptr;
}
Node<T>* getroot(){
return this->root;
}
//Height of the AVL tree
int height(){
return height(this->root);
}
//BalanceFactor of a node
int balance_factor(){
return balance_factor(this->root);
}
void add_node(T data,Node<T>* &node){
if(this->root==nullptr){
Node<T>* new_node= new Node<T>(data);
this->root=new_node;
}
else{
if(data<node->m_data){
if(node->m_left!=nullptr){
add_node(data,node->m_left);
}else{
Node<T>* new_node= new Node<T>(data);
node->m_left=new_node;
node=rebalance(node);
}
}
if(data>node->m_data){
if(node->m_right!=nullptr){
add_node(data,node->m_right);
}else{
Node<T>* new_node= new Node<T>(data);
node->m_right=new_node;
node=rebalance(node);
}
}
}
}
void add_node(T data){
add_node(data,this->root);
}
void level_order_traversal(){
if(this->root==nullptr){
return;
}
std::queue<Node<T>* > q;
q.push(this->root);
while(!q.empty()){
Node<T>* current_node= q.front();
q.pop();
std::cout<<current_node->m_data<<" ";
if(current_node->m_left!=nullptr){
q.push(current_node->m_left);
}
if(current_node->m_right!=nullptr){
q.push(current_node->m_right);
}
}
}
};
return height(this->root);
}
int height(Node<T>* node){
if(node==nullptr){return 0;}
int l_height=height(node->m_left);
int r_height=height(node->m_right);
if(l_height>=r_height){return l_height+1;}
else{return r_height+1;}
}
//BalanceFactor of a node
int balance_factor(){
return balance_factor(this->root);
}
int balance_factor(Node<T>* node){
int l_height= height(node->m_left);
int r_height= height(node->m_right);
int diff= (l_height-(r_height));
return diff;
}
//LL Rotation(Left Rotation)
//when the imbalance factor is caused in the right child's right subtree
Node<T>* ll_rotate(Node<T>* grand_parent_node){
Node<T>* temp = grand_parent_node->m_right;
grand_parent_node->m_right=temp->m_left;
temp->m_left=grand_parent_node;
return temp;
}
//RR Rotate
//when the imabalance is caused in the left childs left subtree
Node<T>* rr_rotate(Node<T>* grand_parent_node){
Node<T>* temp= grand_parent_node->m_left;
grand_parent_node->m_left=temp->m_right;
temp->m_right=grand_parent_node;
return temp;
}
//RL Rotate[Right left Rotation]
//when the imbalance is in the right child's left subtree
Node<T>* rl_rotate(Node<T>* grand_parent_node){
grand_parent_node->m_right=rr_rotate(grand_parent_node->m_right);
return ll_rotate(grand_parent_node);
}
//Lr Rotate[Left right Rotation]
//when the imbalance is in the left child's right subtree
Node<T>* lr_rotate(Node<T>* grand_parent_node){
grand_parent_node->m_left=ll_rotate(grand_parent_node->m_left);
return rr_rotate(grand_parent_node);
}
void add_node(T data,Node<T>* node){
if(this->root==nullptr){
Node<T>* new_node= new Node<T>(data);
this->root=new_node;
}
else{
if(data<node->m_data){
if(node->m_left!=nullptr){
add_node(data,node->m_left);
}else{
Node<T>* new_node= new Node<T>(data);
node->m_left=new_node;
node=rebalance(node);
}
}
if(data>node->m_data){
if(node->m_right!=nullptr){
add_node(data,node->m_right);
}else{
Node<T>* new_node= new Node<T>(data);
node->m_right=new_node;
node=rebalance(node);
}
}
}
}
void add_node(T data){
add_node(data,this->root);
}
Node<T>* rebalance(Node<T>* node){
int bal_fact=balance_factor(node);
if(bal_fact>1){
if(balance_factor(node->m_left)>0){
node=ll_rotate(node);
}else{
node=lr_rotate(node);
}
}
if(bal_fact<-1){
if(balance_factor(node->m_right)>0){
node=rl_rotate(node);
}else{
node=rr_rotate(node);
}
}
return node;
}
void level_order_traversal(){
if(this->root==nullptr){
return;
}
std::queue<Node<T>* > q;
q.push(this->root);
while(!q.empty()){
Node<T>* current_node= q.front();
q.pop();
std::cout<<current_node->m_data<<" ";
if(current_node->m_left!=nullptr){
q.push(current_node->m_left);
}
if(current_node->m_right!=nullptr){
q.push(current_node->m_right);
}
}
}
};