平衡二叉树

来源:互联网 发布:nagle算法 编辑:程序博客网 时间:2024/05/21 17:54
[cpp] view plaincopy
  1. #include "iostream"  
  2. #include "cmath"  
  3. using namespace std;  
  4.   
  5. //首先分析了这几种旋转,发现都和平衡因子有关系,当一个结点平衡因子为2的时候,就该旋转了。  
  6. /*左旋之后,K1子节点的右枝上如果有结点给予K2,左枝上的结点保持不变; 
  7.   右旋之后,K1子节点的左枝上如果有结点给予K2,右枝上的结点保持不变。*/  
  8.   
  9. template<class T>  
  10. class avlTree  
  11. {  
  12. public:  
  13.     avlTree();  
  14.     avlTree(const avlTree &rhs);  
  15.     ~avlTree();  
  16.     const avlTree<T> &operator=(const avlTree &rhs);  
  17.     //int Balance(avlNode *t);   //隐含了一个类嵌套的问题,就是私有类的位置问题。BAB  OR  ABA   
  18.     void insert(const T &x);  
  19.     void remove(const T &x);  
  20.     void inOrderPrint();  
  21.       
  22. private:  
  23.     struct avlNode         
  24.     {  
  25.         T element;  
  26.         avlNode *left;  
  27.         avlNode *right;  
  28.         int height;  
  29.   
  30.         avlNode(const T &theElement, avlNode *lt, avlNode *rt, int h = 0)  
  31.             :element(theElement), left(lt), right(rt), height(h){}  
  32.     };  
  33.     avlNode *root;  
  34.       
  35.     void RR(avlNode *k2);  
  36.     void LL(avlNode *k2);  
  37.     void LR(avlNode *k2);  
  38.     void RL(avlNode *k2);  
  39.     void insert(const T &x, avlNode * &root);   //结点比较的插入  
  40.     void remove(const T &x, avlNode * &root);  
  41.     void inOrderPrint(avlNode * root);  
  42. public:  
  43.     int height(avlNode *t);  
  44. };  
  45.   
  46. template<class T>  
  47. avlTree<T>::avlTree()  
  48. {  
  49.     root = NULL;  
  50. }  
  51.   
  52. template<class T>  
  53. avlTree<T>::~avlTree()  
  54. {  
  55.       
  56. }  
  57.   
  58. template<class T>  
  59. avlTree<T>::avlTree(const avlTree &rhs)  
  60. {  
  61.     root = rhs;  
  62. }  
  63.   
  64. template<class T>  
  65. const avlTree<T> &avlTree<T>::operator=(const avlTree &rhs)  
  66. {  
  67.     if(this = &rhs)  
  68.         return *this;  
  69.     delete root;  
  70.     root = new avlNode;  
  71.     root = rhs.root;  
  72.   
  73.     return *this;  
  74. }  
  75.   
  76. /*if the tree is unbalance ,adjust the smallest unbalance tree to get the balance tree */  
  77. /* the smallest unbalance root node is the nearest to the branches nodes*/  
  78. template<class T>  
  79. int avlTree<T>::height(avlNode *t)  
  80. {  
  81.     return root == NULL ? -1 : root->height;  
  82. }  
  83.     
  84. /*  case one RR    //定义右旋,右旋时K2的左孩子一定不为空。  //外侧插入 
  85.  *          80 ← k2                  60  
  86.  *          /\                        /\  
  87.  *   k1→  60 90         →          20 80 
  88.  *         / \                       /  /\ 
  89.  *        20 75                     ?  75 90 
  90.  *        /        
  91.  *       ?                  
  92.  */  
  93.   
  94. template<class T>   
  95. void avlTree<T>::RR(avlNode *k2)   //the t node is unbalance node   
  96. {  
  97.     avlNode *k1 = k2->left;  
  98.     k2->left = k1->right;  
  99.     k1->right = k2;  
  100.   
  101.     k2->height = max(height(k2->right), height(k2->left)) + 1;  
  102.     k1->height = max(height(k1->left), k2->height) + 1;  
  103.     k2 = k1;  
  104. }  
  105.   
  106. /* case two LL     //定义左旋,左旋时,k2的右孩子一定不为空    //外侧插入 
  107.  *    k2→ 100                        120  
  108.  *          /\                         /\  
  109.  *        85 120   ←k1    →        100 130  
  110.  *           /  \                     / \   \   
  111.  *          110 130                  85 110  ? 
  112.  *               \ 
  113.  *                ? 
  114.  */  
  115. template<class T>  
  116. void avlTree<T>::LL(avlNode *k2)   
  117. {  
  118.     avlNode *k1;   //enter the tree  
  119.     k1 = k2->right;  
  120.     k2->right = k1->left;  
  121.     k1->left = k2;  
  122.   
  123.     k2->height = max(height(k2->right), height(k2->left)) + 1;  
  124.     k1->height = max(height(k2->right), k2->height) + 1;  
  125.     k2 = k1;  
  126. }  
  127.   
  128. /* case three RL       //内测插入  //r有个孩子不为空 
  129.  * the detal can contain two cases 
  130.  * first 
  131.  * 
  132.  *                 LL                      RR 
  133.  *        100     →    p → 100         →        90  
  134.  *         /\                 /\                   /\  
  135.  *   p → 80 120        l → 90 120               80 100  
  136.  *        /\                 /                    /\   \  
  137.  *       60 90 ← r         80                  60 85 120  
  138.  *          /               /\                     / 
  139.  *         85              60 85                  ? 
  140.  *         /                  / 
  141.  *        ?                  ? 
  142.  */    
  143. template<class T>  
  144. void avlTree<T>::RL(avlNode *k2)   
  145. {  
  146.     LL(k2->left);  
  147.     RR(k2);  
  148. }  
  149.   
  150. /* case four LR      //内测插入  //r有个孩子不为空 
  151.  * the detal can contain two cases 
  152.  *                     右旋               左旋  
  153.  *          80          →     80 ← p     →     85  
  154.  *          /\                 /\                 /\  
  155.  *         60 100 ← p        60 85 ← r         80 100  
  156.  *            /\                   \              /  /\  
  157.  *       l →85 120               100            60 90 120  
  158.  *            \                   /\               / 
  159.  *            90                 90 120           ? 
  160.  *            /                  /  
  161.  *           ?                  ? 
  162.  */  
  163. template<class T>  
  164. void avlTree<T>::LR(avlNode *k2)  
  165. {  
  166.     RR(k2->right);  
  167.     LL(k2);  
  168. }  
  169.   
  170. //插入策略,插完调整  
  171. /*  在特殊情况时                 //特殊情况先左旋为正常情况在进行右旋。          
  172.  *             39    <-k2    LL        39   <-k2  RR          30   <-r 
  173.  *             /                       /                      /\   
  174.  *     k1->   20            --->  r-> 30         --->  k1->  20 39    <-k2 
  175.  *             \                      /  
  176.  *        r->  30             k1->   20 
  177.  */      
  178. template<class T>  
  179. void avlTree<T>::insert(const T &x)  
  180. {  
  181.     insert(x, root);  
  182. }  
  183.   
  184. template<class T>  
  185. void avlTree<T>::insert(const T &x, avlNode * &root)  
  186. {  
  187.     if(root == NULL)       //如果根树为block,and then insert at there  
  188.         root = new avlNode(x, NULL, NULL);  
  189.     else if(x < root->element)   //左子树上插入  
  190.     {  
  191.         insert(x, root->left);      
  192.         if(height(root->left) - height(root->right) == 2)  
  193.             if(x < root->left->element)     
  194.                 RR(root);  
  195.             else                  //上述特殊情况下的插入  
  196.                 LR(root);  
  197.     }  
  198.     else if(x > root->element)  
  199.     {  
  200.         insert(x, root->right);  
  201.         if((height(root->right) - height(root->left)) == 2)  
  202.             if(x > root->right->element)  
  203.                 LL(root);  
  204.             else  
  205.                 RL(root);  
  206.     }  
  207.     else   
  208.         ;  
  209.     root->height = max(height(root->left), height(root->right)) + 1;    //旋转之后,现在找到左孩子和右孩子的高度,然后定义自己的高度  
  210. }  
  211.   
  212. //删除策略,将要删的右子结点的最小节点值给了删的那个root->element  
  213. /*  在特殊情况时                          
  214.  *             39     <-root             30             
  215.  *             / \                       / \                      
  216.  *            20 49           --->      20 49        
  217.  *               /                       
  218.  *              30                 delete:30    
  219.  */   
  220.   
  221. template<class T>  
  222. void avlTree<T>::remove(const T &data)   //删除结点  
  223. {  
  224.     remove(data, root);  
  225. }  
  226.   
  227. template<class T>  
  228. void avlTree<T>::remove(const T &data, avlNode * &root)  
  229. {  
  230.     if(root == NULL)   //此节点不存在,  
  231.         return;  
  232.     if(data < root->element)  //左子树上进行删除  
  233.     {  
  234.         remove(data, root->left);   //循环找到那个结点  
  235.         if(height(root->right) - height(root->left) == 2)  
  236.         {  
  237.             if(root->right->left != NULL && (height(root->right->left) > height(root->right->right)))  
  238.                 RL(root);  
  239.             else  
  240.                 RR(root);  
  241.         }  
  242.     }  
  243.     else if(data > root->element)  //右子树上进行删除  
  244.     {  
  245.         remove(data, root->right);  
  246.         if(height(root->left) - height(root->right) == 2)  
  247.         {  
  248.             if((root->left->right) != NULL && (height(root->left->right) > height(root->left->left)))  
  249.                 LR(root);  
  250.             else  
  251.                 LL(root);  
  252.         }  
  253.     }  
  254.     else if(data == root->element)    //这个结点上的删除  
  255.     {  
  256.         if(root->right != NULL && root->left != NULL)   //两个子节点都存在  
  257.         {  
  258.             avlNode *temp = root->right;  
  259.             while(temp != NULL) temp = temp->left;  //将右子结点的最小值替换root  
  260.             root->element = temp->element;  
  261.             remove(root->element, root->right);    //再将那个最小的值清除  
  262.             if(height(root->left) - height(root->right) == 2)  
  263.             {  
  264.             if(root->left->right != NULL && height(root->left->right) > height(root->left->left))  
  265.                 RL(root);  
  266.             else  
  267.                 LL(root);  
  268.             }  
  269.         }  
  270.         else     //只存在一个子节点或不存在子节点  
  271.         {  
  272.             avlNode *temp = root;  
  273.             if(root->left == NULL)    //只有右结点,将其作为根结点  
  274.                 root = root->right;  
  275.             else if(root->right == NULL)  
  276.                 root = root->left;  
  277.             delete temp;  
  278.             temp = NULL;  
  279.         }  
  280.     }  
  281.     if(root == NULL) return;  
  282.     root->height = max(height(root->left), height(root->right)) + 1;  //重设高度  
  283.         return;  
  284. }  
  285.   
  286. template<class T>  
  287. void avlTree<T>::inOrderPrint()    //中序遍历输出  
  288. {  
  289.     inOrderPrint(root);  
  290. }  
  291.   
  292. template<class T>  
  293. void avlTree<T>::inOrderPrint(avlNode * root)    
  294. {  
  295.     if(root == NULL)  
  296.         return;  
  297.     if(root->left)  
  298.         inOrderPrint(root->left);  
  299.     cout << root->element << " ";  
  300.     if(root->right)  
  301.         inOrderPrint(root->right);  
  302.     return;  
  303. }  
  304.   
  305. int main()  
  306. {  
  307.     avlTree<int> tree;  
  308.     tree.insert(20);  
  309.     tree.insert(30);  
  310.     tree.insert(25);  
  311.     tree.remove(25);  
  312.       
  313.     tree.inOrderPrint();  
  314.   
  315.     return 0;  
  316. }  
0 0