#include <iostream>
using namespace std;
struct node//avl tree结点
{
int entry;
struct node *left=NULL;
struct node *right=NULL;
};
class avl_tree
{
public:
node * root=NULL;//根节点
node* insert(int entry,node *current);//插入操作
node* del(int entry,node *current);//删除操作:寻找需要删除的结点
node* del_node(node *current);//删除当前current结点
node* fix(node *current);//删除后调整树的平衡
void show(node *current);//前序遍历输出avl tree
int hight(node *current);//求子树高度
node* rotate(node *current);//旋转操作
node* ll(node *current);
node* lr(node *current);
node* rr(node *current);
node* rl(node *current);
void clear();//清除整棵树
};
class avl_tree avl;
int main()
{
int entry;
int command;
cout<<"Please enter the following commands"<<endl;
cout<<"1:insert an entry and then input a number."<<endl;
cout<<"2:delete an entry and then input a number."<<endl;
cout<<"3:show all the enrties"<<endl;
cout<<"4:empty the tree."<<endl;
while (cin>>command)
{
switch (command)
{
case 1://插入一个结点
cin>>entry;
avl.root = avl.insert(entry,avl.root);
break;
case 2:
cin>>entry;//删除一个结点
avl.root = avl.del(entry,avl.root);
break;
case 3://输出树
avl.show(avl.root);
cout<<endl;
break;
case 4://清除树
avl.clear();
break;
}
}
return 0;
}
node* avl_tree::insert(int entry, node *current)
{
if (root == NULL)//如果是空树,直接插入即可
{
root = new node;
root->entry = entry;
return root;
}
else
{
if (entry == current->entry)//重复元素
{
cout<<"Error! The element already exists."<<endl;
}
else if (entry < current->entry)//从左子树寻找插入位置
{
if (current->left == NULL)
{
current->left = new node;
current->left->entry = entry;
}
else current->left = insert(entry , current->left);//递归插入
}
else if (entry > current->entry)//右子树
{
if (current->right == NULL)
{
current->right = new node;
current->right->entry = entry;
}
else current->right = insert(entry , current->right);//递归
}
current = rotate(current);//调整当前结点,检查是否需要进行旋转操作
}
return current;
}
void avl_tree::show(node *current)
{
if (root == NULL)//空树输出提示
{
cout<<"the tree is empty!";
}
else if (current != NULL)//前序遍历
{
cout<<current->entry<<" ";
show (current->left);
show (current->right);
}
}
node* avl_tree::del(int entry, node *current)
{
if (current == NULL)//表示并未找到要删除的结点
{
cout<<"Error! The target does not exist!"<<endl;
return NULL;
}
if (entry < current->entry)
current->left = del(entry,current->left);//递归左子树
else if (entry > current->entry)
current->right = del(entry,current->right);//递归右子树
else//否则当前结点即要删除的结点
{
current = del_node(current);//删除操作
}
current = rotate(current);//旋转调整
return current;
}
node* avl_tree::del_node(node *current)
{
if (current->left == NULL && current->right == NULL)//如果要删除的结点是叶子结点,直接删除
{
delete current;
return NULL;
}
if (current->left == NULL && current->right != NULL)//如果只有右孩子,将右孩子替换当前结点
{
node *p=current->right;
delete current;
return p;
}
if (current->left != NULL && current->right == NULL)//同上
{
node *p=current->left;
delete current;
return p;
}
//否则将从左子树寻找元素最大的结点进行删除
node *p=current->left;
while (p->right != NULL) p=p->right;//寻找左子树中最大节点
current->entry = p->entry;//将左子树最大元素替换当前结点元素
current->left = fix(current->left);//删除左子树最大元素的结点
return current;
}
int avl_tree::hight(node *current)
{
if (current == NULL) return 0;
else return max(hight(current->left) , hight(current->right))+1;//左右子树高度较大者加一
}
node* avl_tree::rotate(node *current)
{
if (current == NULL) return NULL;
if (hight(current->left) - hight(current->right) > 1)//左子树高度与右子树高度的差大于1
{
node *p = current->left;
if (hight(p->left) - hight(p->right) > 0)
current = ll(current);//ll型旋转
else if (hight(p->right) - hight(p->left) > 0)
current = lr(current);//lr型旋转
}
else if (hight(current->right) - hight(current->left) > 1)//同上,对称操作
{
node *p = current->right;
if (hight(p->right) - hight(p->left) > 0)
current = rr(current);
else if (hight(p->left) - hight(p->right) > 0)
current = rl(current);
}
return current;
}
node* avl_tree::fix(node *current)//删除操作的调整平衡度操作
{
if (current->right == NULL)//递归终点,需删除当前结点(左子树元素最大的结点)
{
node *p=current->left;
delete current;
return p;
}
else current->right = fix(current->right);//递归继续寻找
return rotate(current);//及时调整
}
node* avl_tree::ll(node *current)//ll型旋转
{
node *p = current->left;
current->left = p->right;
p->right = current;
return p;
}
node* avl_tree::lr(node *current)//lr型旋转
{
current->left = rr(current->left);
return ll(current);
}
node* avl_tree::rr(node* current)//rr型旋转
{
node* p = current->right;
current->right = p->left;
p->left = current;
return p;
}
node* avl_tree::rl(node* current)//rl型旋转
{
current->right = ll(current->right);
return rr(current);
}
void avl_tree::clear()//置空操作
{
root = NULL;//这里直接把根节点置为NULL,其实是错误的,会导致内存泄漏。正确的做法应该是递归从叶子结点开始逐层往上delete结点。但是由于这次作业并没有要求这个置空操作,并且我尝试过正确做法,但是bug了,于是在这里稍稍偷了下懒。。。
}
avl tree的插入删除操作代码
最新推荐文章于 2021-12-02 23:52:39 发布