2021-08-06

2 篇文章 0 订阅
1 篇文章 0 订阅

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;
}

weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值