AVL树->图解1

Balance Binary Tree

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

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

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

  1. typedef struct tree_node  
  2. {  
  3.     int data;  
  4.     int bf;//Balance Factor 平衡因子  
  5.     struct tree_node* left;  
  6.     struct tree_node* right;  
  7. }TREE_NODE;  

不平衡可能出现4种

1.LL左左

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

  进行左旋变换    

  1. //左边高L  
  2. void SingleRotateWithLeft(TREE_NODE** root)  
  3. {  
  4.     TREE_NODE* temp;  
  5.     temp =(*root)->left;  
  6.     (*root)->left = temp->right;  
  7.     temp->right = *root;  
  8.     *root = temp;  
  9. }  
2.LR左右

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

一次右旋转->一次左旋

  1. //左边过高LR  
  2. void DoubleRotateWithLeft(TREE_NODE** root)  
  3. {  
  4.     SingleRotateWithRight(&(*root)->left);  
  5.     SingleRotateWithLeft(root);  
  6. }  

3.RR右右

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

一次右旋

  1. //右边高的时L  
  2. void SingleRotateWithRight(TREE_NODE** root)  
  3. {  
  4.     TREE_NODE* temp;  
  5.     temp = (*root)->right;  
  6.     (*root)->right = temp->left;  
  7.     temp->left = *root;  
  8.     *root = temp;  
  9. }  

4.RL右左

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

一次左旋 一次右旋

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

  1. #include "Queue.h"  
  2. #include <iostream>  
  3. using namespace std;  
  4. #include <vector>  
  5. typedef struct avlnode  
  6. {  
  7.     int key;  
  8.     int height;  
  9.     struct avlnode* left;  
  10.     struct avlnode* right;  
  11. }AVLNode;  
  12.   
  13. typedef struct avltree  
  14. {  
  15.     AVLNode* root;  
  16. }AVLTree;  
  17.   
  18. typedef struct   stack  
  19. {  
  20.     AVLNode*  base;    //在栈构造前和销毁后,base的值为NULL  
  21.     AVLNode*  top;       //栈顶指针  
  22.     int    StackSize;       //当前已分配的存储空间,以元素为单位  
  23. }Stack;  
  24.   
  25. AVLTree* CreateAVLTree()  
  26. {  
  27.     AVLTree* tree = new AVLTree;  
  28.     tree->root = NULL;  
  29.     return tree;  
  30. }  
  31.   
  32. int RootHeight(const AVLNode* root)  
  33. {  
  34.     if(root)  
  35.     {  
  36.         return root->height;  
  37.     }  
  38.     else  
  39.     {  
  40.         return 0;  
  41.     }  
  42. }  
  43.   
  44. int Max(const int& a, const int& b)  
  45. {  
  46.     return a > b ? a : b;  
  47. }  
  48. /* 
  49.                       100                              85 
  50.                      /  \               右旋         /    \ 
  51.                    85   120         ------ ->       60    100 
  52.                   /  \                               \    /   \ 
  53.                 60    90                             80  90   120 
  54.                   \ 
  55.                    80 
  56. */  
  57. void SingleRotateWithLeft(AVLNode* &root)  
  58. {  
  59.     AVLNode* temp;  
  60.     temp =root->left;  
  61.    root->left = temp->right;  
  62.     temp->right = root;  
  63.    root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;  
  64.     temp->height = Max(RootHeight(temp->left), RootHeight(temp->right))+1;  
  65.     root = temp;  
  66. }  
  67. /* 
  68.                       80                                   90 
  69.                      /  \              左旋               /  \ 
  70.                    60    90          ---- ->            80    120 
  71.                           /  \                        /  \    / 
  72.                        85  120                      60   85  100 
  73.                             / 
  74.                          100 
  75. */  
  76. void SingleRotateWithRight(AVLNode* & root)  
  77. {  
  78.     AVLNode* temp;  
  79.     temp =root->right;  
  80.     root->right = temp->left;  
  81.     temp->left = root;  
  82.     root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;  
  83.     temp->height = Max(RootHeight(temp->left), RootHeight(temp->right))+1;  
  84.     root = temp;  
  85. }  
  86. /* 
  87.                   100                          100                       90 
  88.                  /  \         左旋            /  \       右旋           / \ 
  89.                 80  120     ------>          90  120    ------>        80 100 
  90.                / \                           /                       /  \   \ 
  91.               60 90                         80                      60  85   120 
  92.                   /                         / \ 
  93.                 85                         60 85 
  94. */  
  95. void DoubleRotateWithLeft(AVLNode* & root)  
  96. {  
  97.     SingleRotateWithRight(root->left);  
  98.     SingleRotateWithLeft(root);  
  99. }  
  100. /* 
  101.               80                              80                                   85 
  102.             /   \             右 旋          /  \               左 旋             / \ 
  103.            60   100          ------>        60   85            ------->          80 100 
  104.                 /  \                              \                             /  /  \ 
  105.                85  120                            100                         60  90  120 
  106.                       \                           /  \ 
  107.                       90                         90  120 
  108. */  
  109. void DoubleRotateWithRight(AVLNode*& root)  
  110. {  
  111.     SingleRotateWithLeft(root->right);  
  112.     SingleRotateWithRight(root);  
  113. }  
  114. AVLNode* FindNode(int data, AVLNode* root) //FindNode  
  115. {  
  116.     if(NULL == root)  
  117.     {  
  118.         return NULL;  
  119.     }  
  120.     else if(data < root->key)  
  121.     {  
  122.         return FindNode(data, root->left);  
  123.     }  
  124.     else if(data > root->key)  
  125.     {  
  126.         return FindNode(data, root->right);  
  127.     }  
  128.     else  
  129.     {  
  130.         return root;  
  131.     }  
  132. }  
  133. AVLNode* FindMin(AVLNode* root) //FindMin  
  134. {  
  135.     if(NULL == root)  
  136.     {  
  137.         return NULL;  
  138.     }  
  139.     else if( NULL== root->left)  
  140.     {  
  141.         return root;  
  142.     }  
  143.     else return FindMin(root->left);  
  144. }  
  145.   
  146. AVLNode* FindMax(AVLNode* root) //FindMax  
  147. {  
  148.     if(NULL == root)  
  149.     {  
  150.         return NULL;  
  151.     }  
  152.     else if( NULL== root->right)  
  153.     {  
  154.         return root;  
  155.     }  
  156.     else return FindMax(root->right);  
  157. }  
  158. bool AVLInsert(AVLNode* &root, int data)  
  159. {  
  160.     if(NULL == root)  
  161.     {  
  162.         root = new AVLNode;  
  163.         if(NULL == root)  
  164.         {  
  165.             return false;  
  166.         }  
  167.         root->key = data;  
  168.         root->height = 0;  
  169.         root->left = NULL;  
  170.         root->right = NULL;  
  171.     }  
  172.     else if(NULL != FindNode(data,root))  
  173.     {  
  174.         cout<<data<<" has been insert ! ";  
  175.     }  
  176.     else if(data < root->key)  
  177.     {  
  178.         AVLInsert(root->left, data);  
  179.         if(2 == RootHeight(root->left) - RootHeight(root->right))  
  180.         {  
  181.             if(data < root->left->key)  
  182.             {  
  183.                 SingleRotateWithLeft(root);  
  184.             }  
  185.             else  
  186.             {  
  187.                 DoubleRotateWithLeft(root);  
  188.             }  
  189.         }  
  190.     }  
  191.     else if(data > root->key)  
  192.     {  
  193.         AVLInsert(root->right, data);  
  194.         if(2 == RootHeight(root->right) - RootHeight(root->left))  
  195.         {  
  196.             if(data > root->right->key)  
  197.             {  
  198.                 SingleRotateWithRight(root);  
  199.             }  
  200.             else  
  201.             {  
  202.                 DoubleRotateWithRight(root);  
  203.             }  
  204.         }  
  205.     }  
  206.     root->height = Max(RootHeight(root->left), RootHeight(root->right))+1;  
  207.     return true;  
  208. }  
  209.   
  210. bool AVLDelete(AVLNode* &root, int data) // 删除  
  211. {  
  212.     AVLNode* temp;  
  213.     if(NULL == root)  
  214.     {  
  215.         return false;  
  216.     }  
  217.     else if(data < root->key)  
  218.     {  
  219.         AVLDelete(root->left, data);  
  220.     }  
  221.     else if(data > root->key)  
  222.     {  
  223.         AVLDelete(root->right, data);  
  224.     }  
  225.     else  
  226.     {  
  227.         if((root->left != NULL) && (root->right != NULL))  
  228.         {  
  229.             temp = FindMin(root->right); //右边找最小值  
  230.             root->key = temp->key; //将找到的值赋给当前root  
  231.             AVLDelete(root->right, root->key); //删除在右边找到的值  
  232.         }  
  233.         else  
  234.         {  
  235.             temp = root;  
  236.             if(NULL == root->left )  
  237.             {  
  238.                 root = root->right;  
  239.             }  
  240.             else if(NULL == root->right)  
  241.             {  
  242.                 root = root->left;  
  243.             }  
  244.             delete temp;  
  245.             temp = NULL;  
  246.         }  
  247.         return true;  
  248.     }  
  249. }  
  250. int TotalNodeNum(AVLNode* root) //节点总数  
  251. {  
  252.     if(root)  
  253.     {  
  254.         int LNodeNum = TotalNodeNum(root->left);  
  255.         int RNodeNum = TotalNodeNum(root->right);  
  256.         return LNodeNum + RNodeNum +1;  
  257.     }  
  258.     return 0;  
  259. }  
  260.   
  261. int LeafNodeNum(AVLNode* root)//叶子节点数  
  262. {  
  263.     int leaf = 0;  
  264.     int LNodeNum = 0;  
  265.     int RNodeNum = 0;  
  266.     if(root)  
  267.     {  
  268.         if(NULL==root->left && NULL == root->right)  
  269.         {  
  270.             leaf =1;  
  271.         }  
  272.         else  
  273.         {  
  274.             LNodeNum = LeafNodeNum(root->left);  
  275.             RNodeNum = LeafNodeNum(root->right);  
  276.             leaf = LNodeNum + RNodeNum;  
  277.         }  
  278.     }  
  279.     else  
  280.     {  
  281.             return 0;  
  282.     }  
  283.    return leaf;  
  284. }  
  285.   
  286. int RootDepth(AVLNode* root)//这个节点的深度  
  287. {  
  288.     if(root)  
  289.     {  
  290.         int LHigh = RootDepth(root->left);  
  291.         int RHigh = RootDepth(root->right);  
  292.         return LHigh > RHigh ? LHigh+1 : RHigh+1;  
  293.     }  
  294.     return 0;  
  295. }  
  296. void SwapRootLeftRight(AVLNode * root)//实现交换每个节点的左右节点  
  297. {  
  298.     AVLNode* temp;  
  299.     if(root)  
  300.     {  
  301.         temp = root->left;  
  302.         root->left = root->right;  
  303.         root->right = temp;  
  304.         SwapRootLeftRight(root->left);  
  305.         SwapRootLeftRight(root->right);  
  306.     }  
  307. }  
  308. void PreOrderTraverse(const AVLNode* root)  
  309. {  
  310.     if(root)  
  311.     {  
  312.         cout << root->key << " ";  
  313.         PreOrderTraverse(root->left);  
  314.         PreOrderTraverse(root->right);  
  315.     }  
  316. }  
  317.   
  318. void InOrderTraverse(const AVLNode* root)  
  319. {  
  320.     if(root)  
  321.     {  
  322.         InOrderTraverse(root->left);  
  323.         cout << root->key << " ";  
  324.         InOrderTraverse(root->right);  
  325.     }  
  326. }  
  327.   
  328. void PostOrderTraverse(const AVLNode* root)  
  329. {  
  330.     if(root)  
  331.     {  
  332.         PostOrderTraverse(root->left);  
  333.         PostOrderTraverse(root->right);  
  334.         cout << root->key << " ";  
  335.     }  
  336. }  
  337. void LevelTraverse( AVLNode* root)  
  338. {  
  339.     if(NULL == root)  
  340.     {  
  341.         return;  
  342.     }  
  343.     vector<AVLNode*>vec;  
  344.     vec.push_back(root);  
  345.     int cur = 0;  
  346.     while(cur < vec.size())  
  347.     {  
  348.         cout<<vec[cur]->key<<" ";  
  349.         if(NULL != vec[cur]->left)  
  350.         {  
  351.             vec.push_back(vec[cur]->left);  
  352.         }  
  353.         if(NULL != vec[cur]->right)  
  354.         {  
  355.             vec.push_back(vec[cur]->right);  
  356.         }  
  357.         cur++;  
  358.     }  
  359. }  
  360. void AllOrderTraverse( AVLNode* root)  
  361. {  
  362.     cout << "PreOrder: ";  
  363.     PreOrderTraverse(root);  
  364.     cout << endl;  
  365.     cout << "InOrder: ";  
  366.     InOrderTraverse(root);  
  367.     cout << endl;  
  368.     cout << "PostOrder: ";  
  369.     PostOrderTraverse(root);  
  370.     cout << endl;  
  371.     cout << "LevelOrder: ";  
  372.     LevelTraverse(root);  
  373.     cout << endl;  
  374. }  
  375. int main()  
  376. {  
  377.     AVLTree* tree = CreateAVLTree();  
  378.     for(int i = 1; i <= 7; i++)  
  379.     {  
  380.         AVLInsert(tree->root, i);  
  381.     }  
  382.     for(int i = 16; i >= 10; i--)  
  383.     {  
  384.         AVLInsert(tree->root, i);  
  385.     }  
  386.     AVLInsert(tree->root, 8);  
  387.     AVLInsert(tree->root, 9);  
  388.     AllOrderTraverse(tree->root);  
  389.     cout<<endl;  
  390.   
  391.     int total = TotalNodeNum(tree->root);  
  392.     int leaf = LeafNodeNum(tree->root);  
  393.     int node2 = leaf-1;//前提是leaf > 1  
  394.     int node1 = total - leaf - node2;  
  395.   
  396.     return 0;  

数组、链表、哈希表、字符串、栈与队列、树、回溯法、贪心算法、动态规划和图论都是计算机科学中常见的数据结构和算法概念: 1. **数组**:是一种线性的数据结构,元素按照顺序排列,通过索引直接访问,支持随机访问,但插入和删除操作效率低。 2. **链表**:由节点组成,每个节点包含数据和指向下一个节点的指针,优点是插入和删除高效,但查找速度慢。 3. **哈希表**:利用哈希函数将键映射到存储位置的数据结构,常用于快速查找,平均时间复杂度接近O(1)。 4. **字符串**:一串字符组成的序列,可以看作特殊类型的数组,支持字符级别的操作。 5. **栈与队列**:栈是一端进出的线性结构,队列是两端进出。栈常用于深度优先搜索,队列常用于广度优先搜索。 6. **树**:非线性数据结构,每个节点有零个或多个子节点,用于组织层次结构,如二叉搜索树、AVL树等。 7. **回溯法**:解决一些组合优化问题的一种递归策略,当发现当前路径无效时,会回退至上一步尝试其他解。 8. **贪心算法**:每一步选择局部最优解,期望达到全局最优,不一定能得到全局最优解,适用于某些问题。 9. **动态规划**:通过把原问题分解成相互依赖的小问题求解,保存中间结果避免重复计算,适用于最优化问题。 10. **图论**:研究顶点和边的关系,包括连通性、路径、最短路径、最小生成树等问题。 11. **高级数据结构**:如堆(用于优先队列)、平衡树(如红黑树、AVL树)、B树和B+树(数据库常用)、布隆过滤器(空间换时间的近似查询)等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值