Size Balanced Tree(SBT) 类模板C++实现(持续更新)

73 篇文章 7 订阅

 Size Balanced Tree(SBT) 类模板C++实现(持续更新)

http://blog.csdn.net/sprintfwater/article/details/8316268

       Size Balanced Tree是OI神犇陈启峰发明的,据说是目前最高效的二叉查找树,搞了好长时间终于弄出来了~这个版本的SBT本来是打算用来实现STL的set的,所以树中不存在两个键值一样的元素,当然改成multiset那样的也不是很麻烦~原本按自己的理解想设计自底向上调整的SBT,结果最后发现这样的SBT有很大的问题最简单的例子就是如果插入的数据是单调有序的,那么显然这棵SBT就会严重倾向一侧,所以必须是自顶向下调整~这次写SBT模板收获很大^_^~大家要是发现bug请留言哈~

被虐。。。重写+debug。。。

  1. // =============================================================================  
  2. //   
  3. //       Filename:  size_balanced_tree.h  
  4. //   
  5. //    Description:  Size Balanced Tree  
  6. //   
  7. //        Version:  1.1  
  8. //        Created:  03/29/2012 01:00:29 PM  
  9. //       Revision:  none  
  10. //       Compiler:  g++  
  11. //   
  12. //         Author:  SphinX (Whisper), topcodersphinx@gmail.com  
  13. //        Company:  HFUT  
  14. //   
  15. // =============================================================================  
  16.   
  17. #ifndef SIZE_BALANCED_TREE  
  18. #define SIZE_BALANCED_TREE  
  19.   
  20. #include <iostream>  
  21. #include <cstring>  
  22. #include "dsexceptions.h"  
  23. using std::cout;  
  24. using std::endl;  
  25.   
  26. template <typename T>  
  27. class SizeBalancedTree  
  28. {  
  29.     private:  
  30.   
  31.         struct SizeBalancedNode  
  32.         {  
  33.             T element;  
  34.             SizeBalancedNode * left;  
  35.             SizeBalancedNode * right;  
  36.             int node_size;  
  37.   
  38.             SizeBalancedNode(const T & _element,   
  39.                     SizeBalancedNode * lt, SizeBalancedNode * rt, int sz = 1)  
  40.                 : element(_element), left(lt), right(rt), node_size(sz) {}  
  41.         };  
  42.   
  43.   
  44.     public:  
  45.   
  46.         SizeBalancedTree()  
  47.         {  
  48.             root = NULL;  
  49.             tree_size = 0;  
  50.         }  
  51.         SizeBalancedTree(SizeBalancedTree & rhs)  
  52.         {  
  53.             this->root = clone(rhs.root);  
  54.             this->tree_size = rhs.size();  
  55.         }  
  56.         ~SizeBalancedTree()  
  57.         {  
  58.             clear();  
  59.         }  
  60.   
  61.         const SizeBalancedTree & operator = (const SizeBalancedTree & rhs)  
  62.         {  
  63.             if (this != &rhs)  
  64.             {  
  65.                 this->clear();  
  66.                 this->root = clone(rhs.root);  
  67.                 this->tree_size = rhs.tree_size;  
  68.             }  
  69.             return (*this);  
  70.         }  
  71.   
  72.         int size() const  
  73.         {  
  74.             return tree_size;  
  75.         }  
  76.         bool empty() const  
  77.         {  
  78.             return size() == 0;  
  79.         }  
  80.         bool contains(const T & x) const  
  81.         {  
  82.             return contains(x, root);  
  83.         }  
  84.         const T & findMin() const  
  85.         {  
  86.             if (empty())  
  87.             {  
  88.                 throw UnderflowException();  
  89.             }  
  90.             return findMin(root)->element;  
  91.         }  
  92.         const T & findMax() const  
  93.         {  
  94.             if (empty())  
  95.             {  
  96.                 throw UnderflowException();  
  97.             }  
  98.             return findMax(root)->element;  
  99.         }  
  100.         int rank(const T & x) const  
  101.         {  
  102.             if (!contains(x))  
  103.             {  
  104.                 return -1;  
  105.             }  
  106.             return rank(x, root);  
  107.         }  
  108.         const T & select(int _rank) const  
  109.         {  
  110.             if (_rank < 0)  
  111.             {  
  112.                 throw UnderflowException();  
  113.             }  
  114.             if (_rank >= size())  
  115.             {  
  116.                 throw OverflowException();  
  117.             }  
  118.             return select(_rank, root)->element;  
  119.         }  
  120.         void showTree() const  
  121.         {  
  122.             showTree(root);  
  123.             return ;  
  124.         }  
  125.   
  126.         void clear()  
  127.         {  
  128.             clear(root);  
  129.             tree_size = 0;  
  130.             return ;  
  131.         }  
  132.         void insert(const T & x)  
  133.         {  
  134.             if (contains(x))  
  135.             {  
  136.                 return ;  
  137.             }  
  138.             ++tree_size;  
  139.             insert(x, root);  
  140.             return ;  
  141.         }  
  142.         void remove(const T & x)  
  143.         {  
  144.             if (!contains(x))  
  145.             {  
  146.                 return ;  
  147.             }  
  148.             --tree_size;  
  149.             remove(x, root);  
  150.             return ;  
  151.         }  
  152.   
  153.   
  154.     private:  
  155.   
  156.         SizeBalancedNode * root;  
  157.         int tree_size;  
  158.   
  159.         int getNodeSize(SizeBalancedNode * t) const  
  160.         {  
  161.             if (NULL == t)  
  162.             {  
  163.                 return 0;  
  164.             }  
  165.             return t->node_size;  
  166.         }  
  167.         bool contains(const T & x, SizeBalancedNode * t) const  
  168.         {  
  169.             while (t != NULL)  
  170.             {  
  171.                 if (x < t->element)  
  172.                 {  
  173.                     t = t->left;  
  174.                 }  
  175.                 else if (t->element < x)  
  176.                 {  
  177.                     t = t->right;  
  178.                 }  
  179.                 else  
  180.                 {  
  181.                     return true;  
  182.                 }  
  183.             }  
  184.             return false;  
  185.         }  
  186.         SizeBalancedNode * clone(SizeBalancedNode * t) const  
  187.         {  
  188.             if (NULL == t)  
  189.             {  
  190.                 return NULL;  
  191.             }  
  192.             return new SizeBalancedNode(t->element,   
  193.                 clone(t->left), clone(t->right));  
  194.         }  
  195.         SizeBalancedNode * findMin(SizeBalancedNode * t) const  
  196.         {  
  197.             if (t != NULL)  
  198.             {  
  199.                 while (t->left != NULL)  
  200.                 {  
  201.                     t = t->left;  
  202.                 }  
  203.             }  
  204.             return t;  
  205.         }  
  206.         SizeBalancedNode * findMax(SizeBalancedNode * t) const  
  207.         {  
  208.             if (t != NULL)  
  209.             {  
  210.                 while (t->right != NULL)  
  211.                 {  
  212.                     t = t->right;  
  213.                 }  
  214.             }  
  215.             return t;  
  216.         }  
  217.         int rank(const T & x, SizeBalancedNode * t) const  
  218.         {  
  219.             int _rank = 0;  
  220.             while (t != NULL)  
  221.             {  
  222.                 if (x < t->element)  
  223.                 {  
  224.                     t = t->left;  
  225.                 }  
  226.                 else if (t->element < x)  
  227.                 {  
  228.                     _rank += getNodeSize(t->left) + 1;  
  229.                     t = t->right;  
  230.                 }  
  231.                 else  
  232.                 {  
  233.                     _rank += getNodeSize(t->left);  
  234.                     break ;  
  235.                 }  
  236.             }  
  237.             return _rank;  
  238.         }  
  239.         SizeBalancedNode * select(int _rank, SizeBalancedNode * t) const  
  240.         {  
  241.             while (t != NULL)  
  242.             {  
  243.                 if (_rank < getNodeSize(t->left))  
  244.                 {  
  245.                     t = t->left;  
  246.                 }  
  247.                 else if (getNodeSize(t->left) < _rank)  
  248.                 {  
  249.                     _rank -= getNodeSize(t->left) + 1;  
  250.                     t = t->right;  
  251.                 }  
  252.                 else  
  253.                 {  
  254.                     break ;  
  255.                 }  
  256.             }  
  257.             return t;  
  258.         }  
  259.         void showTree(SizeBalancedNode * t) const  
  260.         {  
  261.             if (t != NULL)  
  262.             {  
  263.                 cout << "The element of this Node is " << t->element << endl;  
  264.                 if (t->left != NULL)  
  265.                 {  
  266.                     cout << "Walk into left child!" << endl;  
  267.                     showTree(t->left);  
  268.                     cout << "Walk back!" << endl;  
  269.                 }  
  270.                 cout << "The element of this Node is " << t->element << endl;  
  271.                 if (t->right != NULL)  
  272.                 {  
  273.                     cout << "Walk into right child!" << endl;  
  274.                     showTree(t->right);  
  275.                     cout << "Walk back!" << endl;  
  276.                 }  
  277.             }  
  278.             return ;  
  279.         }  
  280.   
  281.         void clear(SizeBalancedNode * & t)  
  282.         {  
  283.             if (t != NULL)  
  284.             {  
  285.                 clear(t->left);  
  286.                 clear(t->right);  
  287.                 delete t;  
  288.                 t = NULL;  
  289.             }  
  290.             return ;  
  291.         }  
  292.         void rotateWithLeft(SizeBalancedNode * & k2)  
  293.         {  
  294.             SizeBalancedNode * k1 = k2->left;  
  295.             k2->left = k1->right;  
  296.             k1->right = k2;  
  297.             k1->node_size = getNodeSize(k2);  
  298.             k2->node_size = getNodeSize(k2->left) + getNodeSize(k2->right) + 1;  
  299.             k2 = k1;  
  300.             return ;  
  301.         }  
  302.         void rotateWithRight(SizeBalancedNode * & k2)  
  303.         {  
  304.             SizeBalancedNode * k1 = k2->right;  
  305.             k2->right = k1->left;  
  306.             k1->left = k2;  
  307.             k1->node_size = getNodeSize(k2);  
  308.             k2->node_size = getNodeSize(k2->left) + getNodeSize(k2->right) + 1;  
  309.             k2 = k1;  
  310.             return ;  
  311.         }  
  312.         void doubleWithLeft(SizeBalancedNode * & t)  
  313.         {  
  314.             rotateWithRight(t->left);  
  315.             rotateWithLeft(t);  
  316.             return ;  
  317.         }  
  318.         void doubleWithRight(SizeBalancedNode * & t)  
  319.         {  
  320.             rotateWithLeft(t->right);  
  321.             rotateWithRight(t);  
  322.             return ;  
  323.         }  
  324.         void maintain(SizeBalancedNode * & t)   //Need to optimize...  
  325.         {  
  326.             if (t->left != NULL)  
  327.             {  
  328.                 if (getNodeSize(t->right) < getNodeSize(t->left->left))  
  329.                 {  
  330.                     rotateWithLeft(t);  
  331.                 }  
  332.                 else if (getNodeSize(t->right) < getNodeSize(t->left->right))  
  333.                 {  
  334.                     doubleWithLeft(t);  
  335.                 }  
  336.             }  
  337.             if (t->right != NULL)  
  338.             {  
  339.                 if (getNodeSize(t->left) < getNodeSize(t->right->right))  
  340.                 {  
  341.                     rotateWithRight(t);  
  342.                 }  
  343.                 else if (getNodeSize(t->left) < getNodeSize(t->right->left))  
  344.                 {  
  345.                     doubleWithRight(t);  
  346.                 }  
  347.             }  
  348.             if (t->left != NULL)  
  349.             {  
  350.                 maintain(t->left);  
  351.             }  
  352.             if (t->right != NULL)  
  353.             {  
  354.                 maintain(t->right);  
  355.             }  
  356.             return ;  
  357.         }  
  358.         void simpleInsert(const T & x, SizeBalancedNode * & t)  
  359.         {  
  360.             if (NULL == t)  
  361.             {  
  362.                 t = new SizeBalancedNode(x, NULL, NULL);  
  363.                 return ;  
  364.             }  
  365.             ++t->node_size;  
  366.             if (x < t->element)  
  367.             {  
  368.                 simpleInsert(x, t->left);  
  369.             }  
  370.             else if (t->element < x)  
  371.             {  
  372.                 simpleInsert(x, t->right);  
  373.             }  
  374.             return ;  
  375.         }  
  376.         void insert(const T & x, SizeBalancedNode * & t)  
  377.         {  
  378.             if (NULL == t)  
  379.             {  
  380.                 t = new SizeBalancedNode(x, NULL, NULL);  
  381.                 return ;  
  382.             }  
  383.             ++t->node_size;  
  384.             if (x < t->element)  
  385.             {  
  386.                 simpleInsert(x, t->left);  
  387.             }  
  388.             else if (t->element < x)  
  389.             {  
  390.                 simpleInsert(x, t->right);  
  391.             }  
  392.             else  
  393.             {  
  394.                 return ;  
  395.             }  
  396.             maintain(t);  
  397.             return ;  
  398.         }  
  399.         void remove(const T & x, SizeBalancedNode * & t)  
  400.         {  
  401.             if (NULL == t)  
  402.             {  
  403.                 return ;  
  404.             }  
  405.             --t->node_size;  
  406.             if (x < t->element)  
  407.             {  
  408.                 remove(x, t->left);  
  409.             }  
  410.             else if (t->element < x)  
  411.             {  
  412.                 remove(x, t->right);  
  413.             }  
  414.             else  
  415.             {  
  416.                 if (t->left != NULL && t->right != NULL)  
  417.                 {  
  418.                     if (getNodeSize(t->left) < getNodeSize(t->right))  
  419.                     {  
  420.                         t->element = findMin(t->right)->element;  
  421.                         remove(t->element, t->right);  
  422.                     }  
  423.                     else  
  424.                     {  
  425.                         t->element = findMax(t->left)->element;  
  426.                         remove(t->element, t->left);  
  427.                     }  
  428.                 }  
  429.                 else  
  430.                 {  
  431.                     SizeBalancedNode * oldNode = t;  
  432.                     t = ((t->left != NULL) ? t->left : t->right);  
  433.                     delete oldNode;  
  434.                     oldNode = NULL;  
  435.                 }  
  436.             }  
  437.             return ;  
  438.         }  
  439.   
  440. };  
  441. /* 
  442.  *template <typename T> 
  443.  *const typename SizeBalancedTree<T>::SizeBalancedNode *  SizeBalancedTree<T>::nil 
  444.  *     = new SizeBalancedTree<T>::SizeBalancedNode(T(), NULL, NULL, 0); 
  445.  */  
  446.   
  447. #endif  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值