Chinaunix首页 | 论坛 | 博客
  • 博客访问: 260268
  • 博文数量: 84
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 927
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-06 23:00
个人简介

growing

文章分类

全部博文(84)

文章存档

2017年(6)

2016年(61)

2015年(17)

我的朋友

分类: C/C++

2016-04-25 13:17:32

1.
以下四种方式时需要旋转


  1. template<class K,class V>
  2. struct AVLTreeNode
  3. {
  4.     AVLTreeNode(const K& key,const V& value)
  5.         :_left(NULL)
  6.         ,_right(NULL)
  7.         ,_parent(NULL)
  8.         ,_key(key)
  9.         ,_value(value)
  10.         ,_bf(0)
  11.     {}
  12.     AVLTreeNode<K,V>* _left;
  13.     AVLTreeNode<K,V>* _right;
  14.     AVLTreeNode<K,V>* _parent;
  15.     K _key;
  16.     V _value;
  17.     int _bf;//平衡因子
  18. };
  19. template<class K,class V>
  20. class AVLTree
  21. {
  22.     typedef AVLTreeNode<K,V> Node;
  23. public:
  24.     AVLTree()
  25.         :_root(NULL)
  26.     {}
  27.     bool Insert(const K& key,const V& value)
  28.     {
  29.         if(_root == NULL)
  30.         {
  31.             _root = new Node(key,value);
  32.             return true;
  33.         }
  34.         //插入
  35.         Node *cur = _root;
  36.         Node *parent = NULL;
  37.         while(cur)
  38.         {
  39.             if(key > cur->_key)
  40.             {
  41.                 parent = cur;
  42.                 cur = cur->_right;
  43.             }
  44.             else if(key < cur->_key)
  45.             {
  46.                 parent = cur;
  47.                 cur = cur->_left;
  48.             }
  49.             else
  50.             {
  51.                 return false;
  52.             }
  53.         }
  54.         cur = new Node(key,value);
  55.         if(key > parent->_key)
  56.         {
  57.             parent->_right = cur;
  58.             cur->_parent = parent;
  59.         }
  60.         else
  61.         {
  62.             parent->_left = cur;
  63.             cur->_parent = parent;
  64.         }
  65.         //调整平衡因子
  66.         bool IsRotate = false;
  67.         while(parent)
  68.         {    
  69.             if(parent->_left == cur)
  70.             {
  71.                 parent->_bf--;
  72.             }
  73.             else
  74.             {
  75.                 parent->_bf++;
  76.             }
  77.             if(parent->_bf == 0)
  78.             {
  79.                 break;
  80.             }
  81.             else if(parent->_bf == 1||parent->_bf == -1)
  82.             {
  83.                 cur = parent;
  84.                 parent = cur->_parent;
  85.             }
  86.             else
  87.             {
  88.                 IsRotate = true;
  89.                 if(parent->_bf == 2)
  90.                 {
  91.                     if(cur->_bf == 1)
  92.                     {
  93.                         RotateL(parent);
  94.                     }
  95.                     else//cur->_bf == -1
  96.                     {
  97.                         RotateRL(parent);
  98.                     }
  99.                 }
  100.                 else//parent->_bf == -2
  101.                 {
  102.                     if(cur->_bf == -1)
  103.                     {
  104.                         RotateR(parent);
  105.                     }
  106.                     else//cur->_bf == 1
  107.                     {
  108.                         RotateLR(parent);
  109.                     }
  110.                 }
  111.                 break;
  112.             }
  113.         }    
  114.         if(IsRotate)
  115.         {
  116.             Node* GrandParent = parent->_parent;
  117.             if(GrandParent == NULL)
  118.             {
  119.                 _root = parent;
  120.             }
  121.             else
  122.             {
  123.                 if(parent->_key < GrandParent->_key)
  124.                 {
  125.                     GrandParent->_left = parent;
  126.                 }
  127.                 else
  128.                 {
  129.                     GrandParent->_right = parent;
  130.                 }
  131.             }
  132.         }
  133.         return true;
  134.     }
  135.     void InOrder()
  136.     {
  137.         _InOrder(_root);
  138.         cout<<endl;
  139.     }
  140.     bool IsBalance()
  141.     {
  142.         return _IsBalance(_root);
  143.     }

  144. protected:
  145.     int _Height(Node* root)
  146.     {
  147.         if(root == NULL)
  148.         {
  149.             return 0;
  150.         }
  151.         int left = _Height(root->_left) + 1;
  152.         int right = _Height(root->_right) + 1;
  153.         return (left>right)?left:right;
  154.     }
  155.     bool _IsBalance(Node* root)
  156.     {
  157.         if(root == NULL)
  158.         {
  159.             return true;
  160.         }
  161.         int left = _Height(root->_left);
  162.         int right = _Height(root->_right);

  163.         int bf = left - right;
  164.         if(abs(bf) > 1)
  165.         {
  166.             return false;
  167.         }
  168.         if(abs(bf) != abs(root->_bf))
  169.         {
  170.             cout<<root->_key<<"平衡因子出错!"<<endl;
  171.             return false;
  172.         }
  173.         return _IsBalance(root->_left)&&_IsBalance(root->_right);
  174.     }
  175.     void _InOrder(Node* root)
  176.     {
  177.         if(root == NULL)
  178.             return;
  179.         _InOrder(root->_left);
  180.         cout<<root->_key<<" ";
  181.         _InOrder(root->_right);
  182.     }
  183.     void RotateL(Node*& parent)
  184.     {
  185.         Node* subR = parent->_right;
  186.         Node* subRL = subR->_left;
  187.         
  188.         parent->_right = subRL;
  189.         if(subRL)
  190.         {
  191.             subRL->_parent = parent;
  192.         }
  193.         subR->_left = parent;
  194.         subR->_parent = parent->_parent;

  195.         parent->_parent = subR;
  196.         parent->_bf = subR->_bf = 0;

  197.         parent = subR;
  198.         
  199.     }
  200.     void RotateR(Node*& parent)
  201.     {
  202.         Node* subL = parent->_left;
  203.         Node* subLR = subL->_right;

  204.         parent->_left = subLR;
  205.         if(subLR)
  206.         {
  207.             subLR->_parent = parent;
  208.         }
  209.         subL->_right = parent;
  210.         subL->_parent = parent->_parent;
  211.     
  212.         parent->_parent = subL;
  213.         parent->_bf = subL->_bf = 0;

  214.         parent = subL;
  215.     }
  216.     void RotateLR(Node*& parent)
  217.     {
  218.         RotateL(parent->_left);
  219.         RotateR(parent);
  220.     }
  221.     void RotateRL(Node*& parent)
  222.     {
  223.         RotateR(parent->_right);
  224.         RotateL(parent);
  225.     }
  226. protected:
  227.     Node* _root;
  228. };
测试:

  1. void test()
  2. {
  3.     AVLTree<int,int> t;
  4.     int a[]={16, 3, 7, 11, 9, 26, 18, 14, 15};
  5.     for(int i = 0;i < sizeof(a)/sizeof(int);++i)
  6.     {
  7.         t.Insert(a[i],i);
  8.     }
  9.     t.InOrder();
  10.     cout<<"IsBalance?"<<t.IsBalance()<<endl;
  11. }
  12. void test2()
  13. {
  14.     AVLTree<int,int> t;
  15.     int a[]={4, 2, 6, 1, 3, 5, 15, 7, 16, 14};
  16.     for(int i = 0;i < sizeof(a)/sizeof(int);++i)
  17.     {
  18.         t.Insert(a[i],i);
  19.     }
  20.     t.InOrder();
  21.     cout<<"IsBalance?"<<t.IsBalance()<<endl;
  22. }


可以看到第二个测试用例并不符合,所以由此知道RL,LR不可以直接调用上面的来旋转,要调整平衡因子,不然插着插着就出错了。
  乖乖来写RL,LR吧。

  1. void RotateRL(Node*& parent)
  2.     {
  3.         Node *subR = parent->_right;
  4.         Node *subRL = subR->_left;
  5.         subR->_left = subRL->_right;

  6.         if (subRL->_right != NULL)
  7.         {
  8.             subRL->_right->_parent = subR;
  9.         }
  10.         subRL->_right = subR;
  11.         subR->_parent = subRL;

  12.         if (subRL->_bf == 0 || subRL->_bf == 1)
  13.         {
  14.             subR->_bf = 0;
  15.         }
  16.         else
  17.         {
  18.             subR->_bf = 1;
  19.         }

  20.         parent->_right = subRL->_left;

  21.         if (subRL->_left != NULL)
  22.         {
  23.             subRL->_left->_parent = parent;
  24.         }
  25.         subRL->_left = parent;
  26.         subRL->_parent = parent->_parent;
  27.         parent->_parent = subRL;
  28.         if (subRL->_bf == 0 || subRL->_bf == -1)
  29.         {
  30.             parent->_bf = 0;
  31.         }
  32.         else
  33.         {
  34.             parent->_bf = -1;
  35.         }
  36.         parent = subRL;
  37.         subRL->_bf = 0;
  38.     }

  39.     void RotateLR(Node*& parent)
  40.     {
  41.         Node *subL = parent->_left;
  42.         Node *subLR = subL->_right;
  43.         subL->_right = subLR->_left;

  44.         if (subLR->_left != NULL)
  45.         {
  46.             subLR->_left->_parent = subL;
  47.         }
  48.         subLR->_left = subL;
  49.         subL->_parent = subLR;

  50.         if (subLR->_bf == 0 || subLR->_bf == -1)
  51.         {
  52.             subL->_bf = 0;
  53.         }
  54.         else
  55.         {
  56.             subL->_bf = -1;
  57.         }

  58.         parent->_left = subLR->_right;

  59.         if (subLR->_right != NULL)
  60.         {
  61.             subLR->_right->_parent = parent;
  62.         }
  63.         subLR->_right = parent;
  64.         subLR->_parent = parent->_parent;
  65.         parent->_parent = subLR;
  66.         if (subLR->_bf == 0 || subLR->_bf == 1)
  67.         {
  68.             parent->_bf = 0;
  69.         }
  70.         else
  71.         {
  72.             parent->_bf = 1;
  73.         }
  74.         parent = subLR;
  75.         subLR->_bf = 0;

  76.     }


阅读(1374) | 评论(0) | 转发(0) |
0

上一篇:Got it!

下一篇:RBtree红黑树

给主人留下些什么吧!~~