• 平衡二叉树


    参考博客:

    https://blog.csdn.net/isunbin/article/details/81707606

    https://blog.csdn.net/qq_25940921/article/details/82183093

    代码有所改动

    struct node{
        int key;
        int height;    //AVL树的平衡因子
        node* left;
        node* right;
        node(int k):key(k),height(1),left(nullptr),right(nullptr){}
    };
    
    class AVLTree
    {
    public:
        AVLTree() {}
        ~AVLTree() {}
        node* L_rotate(node* y);    //左旋
        node* R_rotate(node* y);    //右旋
    
        int height(node* root);
        int getBalance(node* root);
        node* insert(node* root, int key);
        node* delNode(node* root, int key);
        node* findMinNode(node* root);
        void preOrder(node *root);
    private:
    };
    #include <iostream>                                                                            
    #include <stdio.h>
    #include <string.h>
    #include "AVLTree.h"
    using namespace std;
    
    int AVLTree::height(node *N) 
    {
        if(N==nullptr)
            return 0;
        return N->height;
    }
    
    int AVLTree::getBalance(node* N)
    {
        if(N==nullptr)
            return 0;
        return height(N->left)-height(N->right);
    }
    
    node* AVLTree::L_rotate(node* root)
    {
        node* temp = root->right;
        root->right = temp->left;
        temp->left = root;
    
        root->height = max(height(root->left), height(root->right))+1;
        temp->height = max(height(temp->left), height(root->right))+1;
    
        return temp;
    }
    //右旋
    node* AVLTree::R_rotate(node* root)
    {
        node* temp = root->left;
        root->left = temp->right;
        temp->right = root;
    
        root->height = max(height(root->left), height(root->right))+1;
        temp->height = max(height(temp->left), height(temp->right))+1;
    
        return temp;
    }
    
    node* AVLTree::insert(node* root, int key)
    {
        if(root==nullptr)
            return (new node(key));
    
        if(key<root->key)
            root->left = insert(root->left, key);
        else if(key>root->key)
            root->right = insert(root->right, key);
        else
            return root;
    
        root->height = 1+max(height(root->left), height(root->right));
    
        int balance = getBalance(root); //获取当前根节点的平衡因子
    
        if(balance>1 && key < root->left->key)    //LL型
            return R_rotate(root);
    
        if(balance<-1 && key > root->right->key)   //RR型
            return L_rotate(root);
        if(balance>1 && key > root->left->key)    //LR型
        {
            //LR型,先进行左旋再右旋
            root->left = L_rotate(root->left);
            return R_rotate(root);
        }
    
        if(balance<-1 && key < root->right->key)  //RL型
        {
            //RL型,先进行右旋再左旋
            root->right = R_rotate(root->right);
            return L_rotate(root);
        }
    
        return root;
    }
    
    
    void AVLTree::preOrder(node *root)
    {
        if(root)
        {
            printf("%d ", root->key);
            preOrder(root->left);
            preOrder(root->right);
        }
    }
    
    node* AVLTree::findMinNode(node* root)
    {
        if(root==nullptr)
            return root;
        while(root->left)
            root = root->left;
        return root;
    }
    //删除指定节点,删除之后需要对树进行调整
    node* AVLTree::delNode(node* root, int key)
    {
        if(root==nullptr)
            return root;
    
        //进入左子树进行查找
        if(key < root->key)
            root->left = delNode(root->left, key);
        //进入右子树进行查找
        else if(key > root->key)
            root->right = delNode(root->right, key);
        else{
            //如果找到了指定的节点
            if((root->left==nullptr) || (root->right==nullptr))
            {
                node* temp = root->left ? root->left : root->right;
                //如果当前需要被删除的节点没有子节点的时候可以直接将当前节点删除
                if(temp==nullptr)
                {
                    delete root;
                    root=nullptr;
                }
                //如果当前节点仅存在左右子节点中的一个,那么就只要
                //将当前节点的所有信息改变为子节点的信息就行了
                else
                {
                    *root=*temp;
                    delete temp;
                }
            }
            else
            //如果当前待删除节点存在左右两个节点,那么就找到当前节点的右子树的
            //最小的节点,将待删除的节点的key改变为找到的节点的值,最后将新的节点
            //删除即可
            {
                node* temp = findMinNode(root->right);
                root->key = temp->key;
                root->right = delNode(root->right, temp->key);
            }
        }
    
        int balance = getBalance(root);
    
        if(balance > 1 && getBalance(root->left) >= 0)    //LL型
            return R_rotate(root);
    
        if(balance > 1 && getBalance(root->right) < 0)     //LR型
        {
            //LR型,先进行左旋再右旋,注意:左旋是对root的左子树,右旋是对于root
            root->left = L_rotate(root->left);
            return R_rotate(root);
        }
        if(balance < -1 && getBalance(root->right)<=0)     //RR型 
            return L_rotate(root);
    
        if(balance < -1 && getBalance(root->left) > 0)     //RL型
        {
            //RL型,先进行右旋再左旋
            root->right = R_rotate(root->right);
            return L_rotate(root);
        }
    
        //如果上面四种条件都不满足的话,就说明以当前root为根的子树是
        //一棵平衡树,不需要对其进行调整,需要递归到上一层去查看当前
        //root的根是否是一个平衡树,如此网上递归调整整棵树就可以在删
        //除了节点之后,仍然保持树的平衡状态
        
        return root;    //返回调整好的根节点
    }
    #include <iostream>
    #include "AVLTree.h"
    
    
    int main()
    {
        AVLTree avlTree;
        node* root=nullptr;
    
        root =avlTree.insert(root, 9); 
        root =avlTree.insert(root, 5); 
        root =avlTree.insert(root, 10);
        root =avlTree.insert(root, 0); 
        root =avlTree.insert(root, 6); 
        root =avlTree.insert(root, 11);
        root =avlTree.insert(root, -1);
        root =avlTree.insert(root, 1); 
        root =avlTree.insert(root, 2); 
    
        printf("preOrder: 
    ");
        avlTree.preOrder(root);                                                                    
    
        root = avlTree.delNode(root, 10);
        printf("
    
    preOrder after delete 10
    ");
        avlTree.preOrder(root);
    
        std::cout << "Hello world" << std::endl;
        return 0;
    }

  • 相关阅读:
    c++ 动态生成string类型的数组
    c++ string类型的定义及方法
    c++数字和字符串的转换
    c++ 怎么输出保留2位小数的浮点数
    c++中结构体sort()排序
    O(N)时间的排序
    复杂链表的复制
    反转链表
    判断是否为平衡二叉树
    学习笔记_过滤器详细_2(过滤器JavaWeb三大组件之一)
  • 原文地址:https://www.cnblogs.com/jiguang321/p/12072697.html
Copyright © 2020-2023  润新知