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

growing

文章分类

全部博文(84)

文章存档

2017年(6)

2016年(61)

2015年(17)

我的朋友

分类: C/C++

2016-05-08 13:47:50

像细胞一样分裂来维持平衡

  1. template<class K,int M = 3>
  2. struct BtreeNode
  3. {
  4.     BtreeNode()
  5.         :_size(0)
  6.         ,_parent(NULL)
  7.     {
  8.         for(int i = 0;i < M+1;++i)
  9.         {
  10.             _childs[i] = NULL;
  11.         }
  12.     }
  13.     K _key[M];                                         //关键字数组
  14.     size_t _size;                                         //关键字个数
  15.     BtreeNode<K,M>* _childs[M+1]; //孩子
  16.     BtreeNode<K,M>* _parent;            //父亲    
  17. };
  18. template<class K,class V>
  19. struct Pair
  20. {
  21.     Pair(const K&k = K(),const V&v = V())
  22.         :_first(k)
  23.         ,_second(v)
  24.     {}
  25.     K _first;//节点本身
  26.     V _second;//节点所在的位置
  27. };
  28. template<class K,int M = 3>
  29. class Btree
  30. {
  31.     typedef BtreeNode<K,M> Node;
  32. public:
  33.     Btree()
  34.         :_root(NULL)
  35.     {}
  36.     void InOrder()
  37.     {
  38.         _InOrder(_root);
  39.     }
  40.     Pair<Node*,int> Find(const K&key)
  41.     {
  42.         Node* parent = NULL;
  43.         Node* cur = _root;
  44.         while(cur)
  45.         {
  46.             int i = 0;
  47.             while(i < cur->_size && cur->_key[i] < key)
  48.             {
  49.                 ++i;
  50.             }
  51.             if(cur->_key[i] == key)
  52.             {
  53.                 return Pair<Node*,int>(cur,i);
  54.             }
  55.             //如果在此节点里没有找到key,i这时也走到了相应的位置,我们该去它的孩子里找找看
  56.             parent = cur;
  57.             cur = cur->_childs[i];
  58.         }
  59.         return Pair<Node*,int>(parent,-1);
  60.     }
  61.     bool Insert(K& key)
  62.     {
  63.         if(_root == NULL)
  64.         {
  65.             _root = new Node;
  66.             _root->_key[0] = key;
  67.             ++_root->_size;
  68.             return true;
  69.         }
  70.         Pair<Node*,int> ret =Find(key);
  71.         if(ret._second != -1)
  72.         {
  73.             return false;
  74.         }
  75.         
  76.         Node *cur = ret._first;
  77.         Node *child = NULL;

  78.         //往cur插key
  79.         while(1)
  80.         {
  81.             _InsertKey(cur,key,child);
  82.             if(cur->_size < M)
  83.             {
  84.                 return true;
  85.             }
  86.             //插完超过M,开始分裂
  87.             int boundary = M/2;
  88.             
  89.             Node* tmp = new Node;
  90.             size_t index = 0;
  91.             size_t size = cur->_size;
  92.             
  93.             //拷贝key到新分裂出的结点tmp上
  94.             for(int i = boundary+1;i < size;++i)
  95.             {
  96.                 tmp->_key[index++] = cur->_key[i];
  97.                 
  98.                 tmp->_size++;
  99.                 cur->_size--;
  100.             }
  101.             //拷贝孩子
  102.             index = 0;
  103.             for(int i = boundary + 1;i <= size;++i)
  104.             {
  105.                 tmp->_childs[index++] = cur->_childs[i];
  106.                 if(tmp->_childs[index])
  107.                 {
  108.                     tmp->_childs[index]->_parent = tmp;
  109.                 }
  110.             }
  111.             key = cur->_key[boundary];
  112.             cur->_size--;

  113.             //没有根了,即原本的root给分裂了
  114.             if(cur->_parent == NULL)
  115.             {
  116.                 _root = new Node;
  117.                 _root->_key[0] = key;
  118.                 _root->_childs[0] = cur;
  119.                 _root->_childs[1] = tmp;
  120.                 _root->_size = 1;

  121.                 tmp->_parent = _root;
  122.                 cur->_parent = _root;

  123.                 return true;
  124.             }
  125.             cur = cur->_parent;
  126.             child = tmp;
  127.         }
  128.     }
  129. protected:
  130.     void _InOrder(Node* root)
  131.     {
  132.         if(root == NULL)
  133.         {
  134.             return;
  135.         }
  136.         for(size_t i = 0;i < root->_size;++i)
  137.         {
  138.             _InOrder(root->_childs[i]);
  139.             cout<<root->_key[i]<<" ";
  140.         }
  141.         _InOrder(root->_childs[root->_size]);
  142.     }
  143.     void _InsertKey(Node*cur, const K& key,Node* child)//直接插入法
  144.     {
  145.         int i = cur->_size - 1;
  146.         while(i >= 0)
  147.         {
  148.             if(cur->_key[i] > key)
  149.             {
  150.                 cur->_key[i + 1] = cur->_key[i];
  151.                 cur->_childs[i + 2] = cur->_childs[i+1];

  152.                 --i;
  153.             }
  154.             else
  155.             {
  156.                 break;
  157.             }
  158.         }
  159.         cur->_key[i+1] = key;
  160.         cur->_childs[i + 2] = child;
  161.         if(child)
  162.         {
  163.             child->_parent = cur;
  164.         }
  165.         cur->_size++;
  166.     }
  167. protected:
  168.     Node* _root;
  169. };
测试:

  1. void test()
  2. {
  3.     Btree<int,10> t1;
  4.     int a[] = {53, 75, 139, 49, 145, 36, 101};
  5.     for(int i = 0;i < sizeof(a)/sizeof(a[0]);++i)
  6.     {
  7.         t1.Insert(a[i]);
  8.     }
  9.     t1.InOrder();
  10. }


阅读(1168) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~