C++实现AVl自平衡数
可以正常的添加、删除、查找节点。测试通过
老旧的编译器需要吧nullptr换成NULL
主要的操作是对插入或者删除节点后如何判断数需要调整的类型,和如何调整
主要使用的是递归操作
#include <iostream>
#include <stack>
#include <cmath>
using namespace std;
int max(int a, int b) {
if (a >= b)
return a;
else
return b;
}
// acl_node 的树的节点类
template <class T>
class avl_node {
public:
avl_node(T tvalue, int h = 1) :height(h), value(tvalue) {
this->rchild = nullptr;
this->lchild = nullptr;
}
~avl_node() = default; //析构如何实现
int height;
avl_node* rchild;
avl_node* lchild;
T value;
};
//递归求子树高度
template <typename T>
int get_height(avl_node<T>* root) {
if (root == nullptr) return 0;
int left = 0, right = 0;
if (root->lchild != nullptr) { left = get_height(root->lchild); root->lchild->height = left; }
if (root->rchild != nullptr) { right = get_height(root->rchild); root->rchild->height = right; }
return max(left, right) + 1;
}
template <class T>
class avl_tree {
public:
//提供的一些接口函数
//查找
avl_node<T>* find(avl_node<T>* root, T key) {
// 按照BST原则查询节点
if (root == nullptr) return root;
if (root->value > key) {
return this->find(root->lchild, key);
}
else if (root->value < key) {
return this->find(root->rchild, key);
}
else {
cout << "key= " << key << " is finded" << endl;
return root;
}
}
avl_tree(avl_node<T>* root_node) {
avl_root = root_node;
}
avl_tree() = default;
~avl_tree() = default;
/*
* 以下为针对树的操作的实现
*/
// 新增节点,循环遍历找到叶子节点加入
avl_node<T>* push_node(avl_node<T>* root, avl_node<T>* new_node) {
if (root == nullptr) {
return new_node;}
// 按照BST原则插入新节点
if (root->value > new_node->value) {
root->lchild = push_node(root->lchild, new_node);
}
else if (root->value < new_node->value) {
root->rchild = push_node(root->rchild, new_node);
}
else {
cout << "node is already exist" << endl;
}
//遍历数初始化高度
root->height = get_height<T>(root);
// 检测平衡性
avl_node<T>* temp = chack_balance(root);
if (temp != nullptr) root=this->deal_unbalance(temp); //这里必须是赋值给root 也就是给当前子树的根节点实现temp再次赋值给root
return root;
}
// 删除节点循环遍历更新
avl_node<T>* pop_node(avl_node<T>* root, T old_value) {
if (root == nullptr) {
return nullptr;
}
// 按照BST原则删除指定节点节点
if (root->value > old_value ) {
root->lchild = pop_node(root->lchild, old_value);
}
else if (root->value < old_value ) {
root->rchild = pop_node(root->rchild, old_value);
}
else {
avl_node<T>* p;
if (root->lchild != nullptr) {
p = root->lchild;
while (p->rchild != nullptr) p = p->rchild;
root->value = p->value;
root->lchild = pop_node(root->lchild, p->value);
}
else if (root->rchild != nullptr) {
p = root->rchild;
while (p->lchild != nullptr) p = p->lchild;
root->value = p->value;
root->rchild = pop_node(root->rchild, p->value);
}
else {
root = nullptr;
return nullptr;
}
}
//遍历数初始化高度
root->height = get_height<T>(root);
// 检测平衡性
avl_node<T>* temp = chack_balance(root);
if (temp != nullptr) root = this->deal_unbalance(temp);
//遍历数初始化高度
root->height = get_height<T>(root);
return root;
}
// 右旋转
avl_node<T>* right_rotation(avl_node<T>* root) {
avl_node<T>* temp = root->lchild;
root->lchild = temp->rchild;
temp->rchild = root;
//遍历数初始化高度
temp->height = get_height<T>(temp);
return temp;
}
//左旋转
avl_node<T>* left_rotation(avl_node<T>* root) {
avl_node<T>* temp = root->rchild;
root->rchild = temp->lchild;
temp->lchild = root;
//遍历数初始化高度
temp->height = get_height<T>(temp);
return temp;
}
//左右旋转
avl_node<T>* leftright_rotation(avl_node<T>* root) {
root->lchild = left_rotation(root->lchild);
return right_rotation(root);
}
//右左旋转
avl_node<T>* rightleft_rotation(avl_node<T>* root) {
root->rchild = right_rotation(root->rchild);
return left_rotation(root);
}
//判断是否满足平衡条件chack_balance
avl_node<T>* chack_balance(avl_node<T>* root) {
if (root == nullptr) return root;
int left = 0, right = 0;
if (root->lchild != nullptr)left = root->lchild->height;
if (root->rchild != nullptr)right = root->rchild->height;
if (abs(left - right) > 1)
return root;
avl_node<T>* temp=chack_balance(root->lchild);
if (temp != nullptr) return temp;
else return chack_balance(root->rchild);
}
//前序遍历,递归
void pre_traverse(avl_node<T>* root, int ex_dep = 0) {
if (root == nullptr) return;
cout << root->value <<" "<<root->height<< endl;
pre_traverse(root->lchild, ex_dep);
pre_traverse(root->rchild, ex_dep);
}
//后序遍历
void past_traverse(avl_node<T>* root, int ex_dep = 0) {
if (root == nullptr) return;
past_traverse(root->lchild, ex_dep);
past_traverse(root->rchild, ex_dep);
cout << root->value << " " << root->height << endl;
}
//中序遍历
void in_traverse(avl_node<T>* root, int ex_dep = 0) {
if (root == nullptr) return;
in_traverse(root->lchild, ex_dep);
cout << root->value << " " << root->height << endl;
in_traverse(root->rchild, ex_dep);
}
// 前序遍历,heap
void pre_traverse_heap(avl_node<T>* root, int ex_dep = 0) {
if (root == nullptr) return;
stack<avl_node<T> > stack_node;
stack_node->push(root);
avl_node<T>* temp = root;
root->height += ex_dep;
while (!stack_node->empty() || temp != nullptr) {
while (temp != nullptr) {
stack_node->push(temp);
cout << temp->value << endl;
temp = temp->lchild;
}
if (!stack_node->empty()) {
temp = stack_node->top();
stack_node->pop();
//如果这里打印就是中序遍历,相对来说后序比较难
temp = temp->rchidl;
}
}
}
//判断不平衡类型,并处理
avl_node<T>* deal_unbalance(avl_node<T>* root) {
int left = 0, right = 0;
if (root->lchild != nullptr) left = root->lchild->height;
if (root->rchild != nullptr) right = root->rchild->height;
if (left - right >= 2) {
int lleft = 0, lright = 0;
if (root->lchild!=nullptr && root->lchild->lchild != nullptr) lleft = root->lchild->lchild->height;
if (root->lchild != nullptr && root->lchild->rchild != nullptr) lright = root->lchild->rchild->height;
if (lleft-lright >= 1)
root = right_rotation(root);
else
root = leftright_rotation(root);
}
else if (right - left >= 2) {
int rleft = 0, rright = 0;
if (root->rchild != nullptr && root->rchild->rchild != nullptr) rright = root->rchild->rchild->height;
if (root->rchild != nullptr && root->rchild->lchild != nullptr) rleft = root->rchild->lchild->height;
if (rleft-rright >= 1)
root = rightleft_rotation(root);
else
root = left_rotation(root);
}
return root;
}
public:
avl_node<T>* avl_root = nullptr;
};
int main()
{
avl_node<int> root_node(10);
avl_tree<int> s(&root_node);
avl_node<int> new_node(12),new_n1(13), new_n2(15), new_n3(85), new_n4(5), new_n5(25);
s.avl_root = s.push_node(s.avl_root, &new_node);
s.avl_root = s.push_node(s.avl_root, &new_n1);
s.avl_root = s.push_node(s.avl_root, &new_n2);
s.avl_root = s.push_node(s.avl_root, &new_n3);
s.avl_root = s.push_node(s.avl_root, &new_n4);
s.avl_root = s.push_node(s.avl_root, &new_n5);
int key = 12;
avl_node<int>* temp = s.find(s.avl_root,key);
//cout << "Hello world! key= " << key << endl;
//if(temp==nullptr) cout <<" key = " << key<<" not find" << endl;
//else cout << " key = " << key << " is finded " << " height= " << temp->height << endl;
s.avl_root = s.pop_node(s.avl_root, 12);
s.pre_traverse(s.avl_root);
cout << "--------***-------" << endl;
s.in_traverse(s.avl_root);
cout << "--------***-------" << endl;
s.past_traverse(s.avl_root);
//s.pop_node(s.avl_root, 15);
return 0;
}