zoukankan      html  css  js  c++  java
  • AVL树->图解1

    Balance Binary Tree

         是一种二叉排序树,其中每个节点的左子树跟右子树的高度至多为1;因为发现解决平衡二叉树算法的两个人名字命名为AVL树;我们将二叉树节点的左子树深度减去右子树深度的值(Hleft-Hright)=>平衡因子BF(Balance Factor) -1,0,1; 平衡的引入就是为了最大化实现查找为O(logN)

        距离插入节点距离最近,且平衡因子的绝对值大于1的节点为根的子树,我们称为最小不平衡子树

    BBT 实现原理就是在构造二叉排序树时,每当插入一个节点时,先检查是否因插入而破坏了树的平衡性。若是则找到最小不平衡子树,调制最小不平衡子树的链接关系,进行相应旋转,成为新的平衡子树。

    typedef struct tree_node
    {
    	int data;
    	int bf;//Balance Factor 平衡因子
    	struct tree_node* left;
    	struct tree_node* right;
    }TREE_NODE;
    

    不平衡可能出现4种

    1.LL左左

           其中D是新插入的节点,红色节点K2是失去平衡的节点。需要对K1和K2进行左旋调整即将K1作为根,将K2作为K1的左子树,K1的右子树调整为K2的左子树。如下图所示

      进行左旋变换    

    //左边高L
    void SingleRotateWithLeft(TREE_NODE** root)
    {
    	TREE_NODE* temp;
    	temp =(*root)->left;
    	(*root)->left = temp->right;
    	temp->right = *root;
    	*root = temp;
    }
    2.LR左右

          先对K1和K2进行右旋,然后再对K3和K2进行左旋,最终实现平衡。如下图所示

    一次右旋转->一次左旋

    //左边过高LR
    void DoubleRotateWithLeft(TREE_NODE** root)
    {
    	SingleRotateWithRight(&(*root)->left);
    	SingleRotateWithLeft(root);
    }

    3.RR右右

        将K2的右子树更改为K1的左子树,K1的左子树更改为K2即完成的右旋,如下图所示

    一次右旋

    //右边高的时L
    void SingleRotateWithRight(TREE_NODE** root)
    {
    	TREE_NODE* temp;
    	temp = (*root)->right;
    	(*root)->right = temp->left;
    	temp->left = *root;
    	*root = temp;
    }

    4.RL右左

       右左双旋:先对K1和K2进行左旋,然后在对K2和K3进行右旋,最终实现平衡。如下图所示

    一次左旋一次右旋

          上面是AVL树四种旋转情况,下面来实现一下AVL树。AVL树的实现跟上一章讲的二叉查找树相似,区别在于在插入和删除节点是需要对树进行调整以满足平衡条件

    #include "Queue.h"
    #include <iostream>
    using namespace std;
    #include <vector>
    typedef struct avlnode
    {
        int key;
        int height;
        struct avlnode* left;
        struct avlnode* right;
    }AVLNode;
    
    typedef struct avltree
    {
        AVLNode* root;
    }AVLTree;
    
    typedef struct   stack
    {
        AVLNode*  base;    //在栈构造前和销毁后,base的值为NULL
        AVLNode*  top;       //栈顶指针
        int    StackSize;       //当前已分配的存储空间,以元素为单位
    }Stack;
    
    AVLTree* CreateAVLTree()
    {
        AVLTree* tree = new AVLTree;
        tree->root = NULL;
        return tree;
    }
    
    int RootHeight(const AVLNode* root)
    {
        if(root)
        {
            return root->height;
        }
        else
        {
            return 0;
        }
    }
    
    int Max(const int& a, const int& b)
    {
        return a > b ? a : b;
    }
    /*
                          100                              85
                         /                 右旋         /    
                       85   120         ------ ->       60    100
                      /                                     /   
                    60    90                             80  90   120
                      
                       80
    */
    void SingleRotateWithLeft(AVLNode* &root)
    {
        AVLNode* temp;
        temp =root->left;
       root->left = temp->right;
        temp->right = root;
       root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;
        temp->height = Max(RootHeight(temp->left), RootHeight(temp->right))+1;
        root = temp;
    }
    /*
                          80                                   90
                         /                左旋               /  
                       60    90          ---- ->            80    120
                              /                          /      /
                           85  120                      60   85  100
                                /
                             100
    */
    void SingleRotateWithRight(AVLNode* & root)
    {
        AVLNode* temp;
        temp =root->right;
        root->right = temp->left;
        temp->left = root;
        root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;
        temp->height = Max(RootHeight(temp->left), RootHeight(temp->right))+1;
        root = temp;
    }
    /*
                      100                          100                       90
                     /           左旋            /         右旋           / 
                    80  120     ------>          90  120    ------>        80 100
                   /                            /                       /     
                  60 90                         80                      60  85   120
                      /                         / 
                    85                         60 85
    */
    void DoubleRotateWithLeft(AVLNode* & root)
    {
        SingleRotateWithRight(root->left);
        SingleRotateWithLeft(root);
    }
    /*
                  80                              80                                   85
                /                右 旋          /                 左 旋             / 
               60   100          ------>        60   85            ------->          80 100
                    /                                                             /  /  
                   85  120                            100                         60  90  120
                                                     /  
                          90                         90  120
    */
    void DoubleRotateWithRight(AVLNode*& root)
    {
        SingleRotateWithLeft(root->right);
        SingleRotateWithRight(root);
    }
    AVLNode* FindNode(int data, AVLNode* root) //FindNode
    {
        if(NULL == root)
        {
            return NULL;
        }
        else if(data < root->key)
        {
            return FindNode(data, root->left);
        }
        else if(data > root->key)
        {
            return FindNode(data, root->right);
        }
        else
        {
            return root;
        }
    }
    AVLNode* FindMin(AVLNode* root) //FindMin
    {
        if(NULL == root)
        {
            return NULL;
        }
        else if( NULL== root->left)
        {
            return root;
        }
        else return FindMin(root->left);
    }
    
    AVLNode* FindMax(AVLNode* root) //FindMax
    {
        if(NULL == root)
        {
            return NULL;
        }
        else if( NULL== root->right)
        {
            return root;
        }
        else return FindMax(root->right);
    }
    bool AVLInsert(AVLNode* &root, int data)
    {
        if(NULL == root)
        {
            root = new AVLNode;
            if(NULL == root)
            {
                return false;
            }
            root->key = data;
            root->height = 0;
            root->left = NULL;
            root->right = NULL;
        }
        else if(NULL != FindNode(data,root))
        {
            cout<<data<<" has been insert ! ";
        }
        else if(data < root->key)
        {
            AVLInsert(root->left, data);
            if(2 == RootHeight(root->left) - RootHeight(root->right))
            {
                if(data < root->left->key)
                {
                    SingleRotateWithLeft(root);
                }
                else
                {
                    DoubleRotateWithLeft(root);
                }
            }
        }
        else if(data > root->key)
        {
            AVLInsert(root->right, data);
            if(2 == RootHeight(root->right) - RootHeight(root->left))
            {
                if(data > root->right->key)
                {
                    SingleRotateWithRight(root);
                }
                else
                {
                    DoubleRotateWithRight(root);
                }
            }
        }
        root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;
        return true;
    }
    
    bool AVLDelete(AVLNode* &root, int data) // 删除
    {
        AVLNode* temp;
        if(NULL == root)
        {
            return false;
        }
        else if(data < root->key)
        {
            AVLDelete(root->left, data);
        }
        else if(data > root->key)
        {
            AVLDelete(root->right, data);
        }
        else
        {
            if((root->left != NULL) && (root->right != NULL))
            {
                temp = FindMin(root->right); //右边找最小值
                root->key = temp->key; //将找到的值赋给当前root
                AVLDelete(root->right, root->key); //删除在右边找到的值
            }
            else
            {
                temp = root;
                if(NULL == root->left )
                {
                    root = root->right;
                }
                else if(NULL == root->right)
                {
                    root = root->left;
                }
                delete temp;
                temp = NULL;
            }
            return true;
        }
    }
    int TotalNodeNum(AVLNode* root) //节点总数
    {
        if(root)
        {
            int LNodeNum = TotalNodeNum(root->left);
            int RNodeNum = TotalNodeNum(root->right);
            return LNodeNum + RNodeNum +1;
        }
        return 0;
    }
    
    int LeafNodeNum(AVLNode* root)//叶子节点数
    {
        int leaf = 0;
        int LNodeNum = 0;
        int RNodeNum = 0;
        if(root)
        {
            if(NULL==root->left && NULL == root->right)
            {
                leaf =1;
            }
            else
            {
                LNodeNum = LeafNodeNum(root->left);
                RNodeNum = LeafNodeNum(root->right);
                leaf = LNodeNum + RNodeNum;
            }
        }
        else
        {
                return 0;
        }
       return leaf;
    }
    
    int RootDepth(AVLNode* root)//这个节点的深度
    {
        if(root)
        {
            int LHigh = RootDepth(root->left);
            int RHigh = RootDepth(root->right);
            return LHigh > RHigh ? LHigh+1 : RHigh+1;
        }
        return 0;
    }
    void SwapRootLeftRight(AVLNode * root)//实现交换每个节点的左右节点
    {
        AVLNode* temp;
        if(root)
        {
            temp = root->left;
            root->left = root->right;
            root->right = temp;
            SwapRootLeftRight(root->left);
            SwapRootLeftRight(root->right);
        }
    }
    void PreOrderTraverse(const AVLNode* root)
    {
        if(root)
        {
            cout << root->key << " ";
            PreOrderTraverse(root->left);
            PreOrderTraverse(root->right);
        }
    }
    
    void InOrderTraverse(const AVLNode* root)
    {
        if(root)
        {
            InOrderTraverse(root->left);
            cout << root->key << " ";
            InOrderTraverse(root->right);
        }
    }
    
    void PostOrderTraverse(const AVLNode* root)
    {
        if(root)
        {
            PostOrderTraverse(root->left);
            PostOrderTraverse(root->right);
            cout << root->key << " ";
        }
    }
    void LevelTraverse( AVLNode* root)
    {
        if(NULL == root)
        {
            return;
        }
        vector<AVLNode*>vec;
        vec.push_back(root);
        int cur = 0;
        while(cur < vec.size())
        {
            cout<<vec[cur]->key<<" ";
            if(NULL != vec[cur]->left)
            {
                vec.push_back(vec[cur]->left);
            }
            if(NULL != vec[cur]->right)
            {
                vec.push_back(vec[cur]->right);
            }
            cur++;
        }
    }
    void AllOrderTraverse( AVLNode* root)
    {
        cout << "PreOrder: ";
        PreOrderTraverse(root);
        cout << endl;
        cout << "InOrder: ";
        InOrderTraverse(root);
        cout << endl;
        cout << "PostOrder: ";
        PostOrderTraverse(root);
        cout << endl;
        cout << "LevelOrder: ";
        LevelTraverse(root);
        cout << endl;
    }
    int main()
    {
        AVLTree* tree = CreateAVLTree();
        for(int i = 1; i <= 7; i++)
        {
            AVLInsert(tree->root, i);
        }
        for(int i = 16; i >= 10; i--)
        {
            AVLInsert(tree->root, i);
        }
        AVLInsert(tree->root, 8);
        AVLInsert(tree->root, 9);
        AllOrderTraverse(tree->root);
        cout<<endl;
    
        int total = TotalNodeNum(tree->root);
        int leaf = LeafNodeNum(tree->root);
        int node2 = leaf-1;//前提是leaf > 1
        int node1 = total - leaf - node2;
    
        return 0;
    }
    


    关注公众号 海量干货等你
  • 相关阅读:
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734455.html
Copyright © 2011-2022 走看看