avl tree的插入删除操作代码

#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了,于是在这里稍稍偷了下懒。。。
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值