B+树(C++实现)

来源:互联网 发布:pdf文件朗读软件 编辑:程序博客网 时间:2024/06/15 16:37

定义:

一棵M(M>2)阶的B+树满足以下定义:

1.B+树中包含两种类型的结点:内结点和叶子结点。内结点存有关键字和孩子结点的指针,叶子结点存有关键字和数据;

2.每一个关键字都会在叶子结点中出现,叶子结点按照关键字的大小排序,叶子结点中会存有指向兄弟结点的指针;

3.一棵B+树一般存有两个指针:一个指向根结点,一个指向存有最小关键字的叶子结点;

4.每个内结点至多有M个子树;

5.每个非根内结点至少有ceiling(M/2)个子树;

6.N个子树对应N-1个关键字(ps:另外一种说法是N个子树对应N个关键字,我参考的维基百科的定义http://en.wikipedia.org/wiki/B%2B_tree);

7.一个结点内关键字key1、key2、...、keyN,对应着N+1个孩子结点指针child1、child2、...、childN+1,且有child1<key1<child2<key2<...<keyN<childN+1;

8.叶子结点的关键字个数可以单独设置,一般和内结点关键字个数相同。

一图胜千言(图片来源:维基百科):

File:Bplustree.png

实现

  • BPlus_node.h
[cpp] view plaincopy
  1. #ifndef BPLUS_NODE  
  2. #define BPLUS_NODE  
  3.   
  4. #define NULL 0  
  5.   
  6. enum NODE_TYPE{INTERNAL, LEAF};        // 结点类型:内结点、叶子结点  
  7. enum SIBLING_DIRECTION{LEFT, RIGHT};   // 兄弟结点方向:左兄弟结点、右兄弟结点  
  8. typedef float KeyType;                 // 键类型  
  9. typedef int DataType;                  // 值类型  
  10. const int ORDER = 7;                   // B+树的阶(非根内结点的最小子树个数)  
  11. const int MINNUM_KEY = ORDER-1;        // 最小键值个数  
  12. const int MAXNUM_KEY = 2*ORDER-1;      // 最大键值个数  
  13. const int MINNUM_CHILD = MINNUM_KEY+1; // 最小子树个数  
  14. const int MAXNUM_CHILD = MAXNUM_KEY+1; // 最大子树个数  
  15. const int MINNUM_LEAF = MINNUM_KEY;    // 最小叶子结点键值个数  
  16. const int MAXNUM_LEAF = MAXNUM_KEY;    // 最大叶子结点键值个数  
  17.   
  18. // 结点基类  
  19. class CNode{  
  20. public:  
  21.     CNode();  
  22.     virtual ~CNode();  
  23.   
  24.     NODE_TYPE getType() const {return m_Type;}  
  25.     void setType(NODE_TYPE type){m_Type = type;}  
  26.     int getKeyNum() const {return m_KeyNum;}  
  27.     void setKeyNum(int n){m_KeyNum = n;}  
  28.     KeyType getKeyValue(int i) const {return m_KeyValues[i];}  
  29.     void setKeyValue(int i, KeyType key){m_KeyValues[i] = key;}  
  30.     int getKeyIndex(KeyType key)const;  // 找到键值在结点中存储的下标  
  31.     // 纯虚函数,定义接口  
  32.     virtual void removeKey(int keyIndex, int childIndex)=0;  // 从结点中移除键值  
  33.     virtual void split(CNode* parentNode, int childIndex)=0; // 分裂结点  
  34.     virtual void mergeChild(CNode* parentNode, CNode* childNode, int keyIndex)=0;  // 合并结点  
  35.     virtual void clear()=0; // 清空结点,同时会清空结点所包含的子树结点  
  36.     virtual void borrowFrom(CNode* destNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d)=0; // 从兄弟结点中借一个键值  
  37.     virtual int getChildIndex(KeyType key, int keyIndex)const=0;  // 根据键值获取孩子结点指针下标  
  38. protected:  
  39.     NODE_TYPE m_Type;  
  40.     int m_KeyNum;  
  41.     KeyType m_KeyValues[MAXNUM_KEY];  
  42. };  
  43.   
  44. // 内结点  
  45. class CInternalNode : public CNode{  
  46. public:  
  47.     CInternalNode();  
  48.     virtual ~CInternalNode();  
  49.   
  50.     CNode* getChild(int i) const {return m_Childs[i];}  
  51.     void setChild(int i, CNode* child){m_Childs[i] = child;}  
  52.     void insert(int keyIndex, int childIndex, KeyType key, CNode* childNode);  
  53.     virtual void split(CNode* parentNode, int childIndex);  
  54.     virtual void mergeChild(CNode* parentNode, CNode* childNode, int keyIndex);  
  55.     virtual void removeKey(int keyIndex, int childIndex);  
  56.     virtual void clear();  
  57.     virtual void borrowFrom(CNode* destNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d);  
  58.     virtual int getChildIndex(KeyType key, int keyIndex)const;  
  59. private:  
  60.     CNode* m_Childs[MAXNUM_CHILD];  
  61. };  
  62.   
  63. // 叶子结点  
  64. class CLeafNode : public CNode{  
  65. public:  
  66.     CLeafNode();  
  67.     virtual ~CLeafNode();  
  68.   
  69.     CLeafNode* getLeftSibling() const {return m_LeftSibling;}  
  70.     void setLeftSibling(CLeafNode* node){m_LeftSibling = node;}  
  71.     CLeafNode* getRightSibling() const {return m_RightSibling;}  
  72.     void setRightSibling(CLeafNode* node){m_RightSibling = node;}  
  73.     DataType getData(int i) const {return m_Datas[i];}  
  74.     void setData(int i, const DataType& data){m_Datas[i] = data;}  
  75.     void insert(KeyType key, const DataType& data);  
  76.     virtual void split(CNode* parentNode, int childIndex);  
  77.     virtual void mergeChild(CNode* parentNode, CNode* childNode, int keyIndex);  
  78.     virtual void removeKey(int keyIndex, int childIndex);  
  79.     virtual void clear();  
  80.     virtual void borrowFrom(CNode* destNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d);  
  81.     virtual int getChildIndex(KeyType key, int keyIndex)const;  
  82. private:  
  83.     CLeafNode* m_LeftSibling;  
  84.     CLeafNode* m_RightSibling;  
  85.     DataType m_Datas[MAXNUM_LEAF];  
  86. };  
  87. #endif  
  • BPlus_node.cpp
[cpp] view plaincopy
  1. #include "BPlus_node.h"  
  2.   
  3. // CNode  
  4. CNode::CNode(){  
  5.     setType(LEAF);  
  6.     setKeyNum(0);  
  7. }  
  8.   
  9. CNode::~CNode(){  
  10.     setKeyNum(0);  
  11. }  
  12.   
  13. int CNode::getKeyIndex(KeyType key)const  
  14. {  
  15.     int left = 0;  
  16.     int right = getKeyNum()-1;  
  17.     int current;  
  18.     while(left!=right)  
  19.     {  
  20.         current = (left+right)/2;  
  21.         KeyType currentKey = getKeyValue(current);  
  22.         if (key>currentKey)  
  23.         {  
  24.             left = current+1;  
  25.         }  
  26.         else  
  27.         {  
  28.             right = current;  
  29.         }  
  30.     }  
  31.     return left;  
  32. }  
  33.   
  34. // CInternalNode  
  35. CInternalNode::CInternalNode():CNode(){  
  36.     setType(INTERNAL);  
  37. }  
  38.   
  39. CInternalNode::~CInternalNode(){  
  40.       
  41. }  
  42.   
  43. void CInternalNode::clear()  
  44. {  
  45.     for (int i=0; i<=m_KeyNum; ++i)  
  46.     {  
  47.         m_Childs[i]->clear();  
  48.         delete m_Childs[i];  
  49.         m_Childs[i] = NULL;  
  50.     }  
  51. }  
  52.   
  53. void CInternalNode::split(CNode* parentNode, int childIndex)  
  54. {  
  55.     CInternalNode* newNode = new CInternalNode();//分裂后的右节点  
  56.     newNode->setKeyNum(MINNUM_KEY);  
  57.     int i;  
  58.     for (i=0; i<MINNUM_KEY; ++i)// 拷贝关键字的值  
  59.     {  
  60.         newNode->setKeyValue(i, m_KeyValues[i+MINNUM_CHILD]);  
  61.     }  
  62.     for (i=0; i<MINNUM_CHILD; ++i) // 拷贝孩子节点指针  
  63.     {  
  64.         newNode->setChild(i, m_Childs[i+MINNUM_CHILD]);  
  65.     }  
  66.     setKeyNum(MINNUM_KEY);  //更新左子树的关键字个数  
  67.     ((CInternalNode*)parentNode)->insert(childIndex, childIndex+1, m_KeyValues[MINNUM_KEY], newNode);  
  68. }  
  69.   
  70. void CInternalNode::insert(int keyIndex, int childIndex, KeyType key, CNode* childNode){  
  71.     int i;  
  72.     for (i=getKeyNum(); i>keyIndex; --i)//将父节点中的childIndex后的所有关键字的值和子树指针向后移一位  
  73.     {  
  74.         setChild(i+1,m_Childs[i]);  
  75.         setKeyValue(i,m_KeyValues[i-1]);  
  76.     }  
  77.     if (i==childIndex)  
  78.     {  
  79.         setChild(i+1, m_Childs[i]);  
  80.     }  
  81.     setChild(childIndex, childNode);  
  82.     setKeyValue(keyIndex, key);  
  83.     setKeyNum(m_KeyNum+1);  
  84. }  
  85.   
  86. void CInternalNode::mergeChild(CNode* parentNode, CNode* childNode, int keyIndex)  
  87. {  
  88.     // 合并数据  
  89.     insert(MINNUM_KEY, MINNUM_KEY+1, parentNode->getKeyValue(keyIndex), ((CInternalNode*)childNode)->getChild(0));  
  90.     int i;  
  91.     for (i=1; i<=childNode->getKeyNum(); ++i)  
  92.     {  
  93.         insert(MINNUM_KEY+i, MINNUM_KEY+i+1, childNode->getKeyValue(i-1), ((CInternalNode*)childNode)->getChild(i));  
  94.     }  
  95.     //父节点删除index的key  
  96.     parentNode->removeKey(keyIndex, keyIndex+1);  
  97.     delete ((CInternalNode*)parentNode)->getChild(keyIndex+1);  
  98. }  
  99.   
  100. void CInternalNode::removeKey(int keyIndex, int childIndex)  
  101. {  
  102.     for (int i=0; i<getKeyNum()-keyIndex-1; ++i)  
  103.     {  
  104.         setKeyValue(keyIndex+i, getKeyValue(keyIndex+i+1));  
  105.         setChild(childIndex+i, getChild(childIndex+i+1));  
  106.     }  
  107.     setKeyNum(getKeyNum()-1);  
  108. }  
  109.   
  110. void CInternalNode::borrowFrom(CNode* siblingNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d)  
  111. {  
  112.     switch(d)  
  113.     {  
  114.     case LEFT:  // 从左兄弟结点借  
  115.         {  
  116.             insert(0, 0, parentNode->getKeyValue(keyIndex), ((CInternalNode*)siblingNode)->getChild(siblingNode->getKeyNum()));  
  117.             parentNode->setKeyValue(keyIndex, siblingNode->getKeyValue(siblingNode->getKeyNum()-1));  
  118.             siblingNode->removeKey(siblingNode->getKeyNum()-1, siblingNode->getKeyNum());  
  119.         }  
  120.         break;  
  121.     case RIGHT:  // 从右兄弟结点借  
  122.         {  
  123.             insert(getKeyNum(), getKeyNum()+1, parentNode->getKeyValue(keyIndex), ((CInternalNode*)siblingNode)->getChild(0));  
  124.             parentNode->setKeyValue(keyIndex, siblingNode->getKeyValue(0));  
  125.             siblingNode->removeKey(0, 0);  
  126.         }  
  127.         break;  
  128.     default:  
  129.         break;  
  130.     }  
  131. }  
  132.   
  133. int CInternalNode::getChildIndex(KeyType key, int keyIndex)const  
  134. {  
  135.     if (key==getKeyValue(keyIndex))  
  136.     {  
  137.         return keyIndex+1;  
  138.     }  
  139.     else  
  140.     {  
  141.         return keyIndex;  
  142.     }  
  143. }  
  144.   
  145. // CLeafNode  
  146. CLeafNode::CLeafNode():CNode(){  
  147.     setType(LEAF);  
  148.     setLeftSibling(NULL);  
  149.     setRightSibling(NULL);  
  150. }  
  151.   
  152. CLeafNode::~CLeafNode(){  
  153.   
  154. }  
  155.   
  156. void CLeafNode::clear()  
  157. {  
  158.     for (int i=0; i<m_KeyNum; ++i)  
  159.     {  
  160.         // if type of m_Datas is pointer  
  161.         //delete m_Datas[i];  
  162.         //m_Datas[i] = NULL;  
  163.     }  
  164. }  
  165.   
  166. void CLeafNode::insert(KeyType key, const DataType& data)  
  167. {  
  168.     int i;  
  169.     for (i=m_KeyNum; i>=1 && m_KeyValues[i-1]>key; --i)  
  170.     {  
  171.         setKeyValue(i, m_KeyValues[i-1]);  
  172.         setData(i, m_Datas[i-1]);  
  173.     }  
  174.     setKeyValue(i, key);  
  175.     setData(i, data);  
  176.     setKeyNum(m_KeyNum+1);  
  177. }  
  178.   
  179. void CLeafNode::split(CNode* parentNode, int childIndex)  
  180. {  
  181.     CLeafNode* newNode = new CLeafNode();//分裂后的右节点  
  182.     setKeyNum(MINNUM_LEAF);    
  183.     newNode->setKeyNum(MINNUM_LEAF+1);  
  184.     newNode->setRightSibling(getRightSibling());  
  185.     setRightSibling(newNode);  
  186.     newNode->setLeftSibling(this);  
  187.     int i;  
  188.     for (i=0; i<MINNUM_LEAF+1; ++i)// 拷贝关键字的值  
  189.     {  
  190.         newNode->setKeyValue(i, m_KeyValues[i+MINNUM_LEAF]);  
  191.     }  
  192.     for (i=0; i<MINNUM_LEAF+1; ++i)// 拷贝数据  
  193.     {  
  194.         newNode->setData(i, m_Datas[i+MINNUM_LEAF]);  
  195.     }  
  196.     ((CInternalNode*)parentNode)->insert(childIndex, childIndex+1, m_KeyValues[MINNUM_LEAF], newNode);  
  197. }  
  198.   
  199. void CLeafNode::mergeChild(CNode* parentNode, CNode* childNode, int keyIndex)  
  200. {  
  201.     // 合并数据  
  202.     for (int i=0; i<childNode->getKeyNum(); ++i)  
  203.     {  
  204.         insert(childNode->getKeyValue(i), ((CLeafNode*)childNode)->getData(i));  
  205.     }  
  206.     setRightSibling(((CLeafNode*)childNode)->getRightSibling());  
  207.     //父节点删除index的key,  
  208.     parentNode->removeKey(keyIndex, keyIndex+1);  
  209. }  
  210.   
  211. void CLeafNode::removeKey(int keyIndex, int childIndex)  
  212. {  
  213.     for (int i=keyIndex; i<getKeyNum()-1; ++i)  
  214.     {  
  215.         setKeyValue(i, getKeyValue(i+1));  
  216.         setData(i, getData(i+1));  
  217.     }  
  218.     setKeyNum(getKeyNum()-1);  
  219. }  
  220.   
  221. void CLeafNode::borrowFrom(CNode* siblingNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d)  
  222. {  
  223.     switch(d)  
  224.     {  
  225.     case LEFT:  // 从左兄弟结点借  
  226.         {  
  227.             insert(siblingNode->getKeyValue(siblingNode->getKeyNum()-1), ((CLeafNode*)siblingNode)->getData(siblingNode->getKeyNum()-1));  
  228.             siblingNode->removeKey(siblingNode->getKeyNum()-1, siblingNode->getKeyNum()-1);  
  229.             parentNode->setKeyValue(keyIndex, getKeyValue(0));             
  230.         }  
  231.         break;  
  232.     case RIGHT:  // 从右兄弟结点借  
  233.         {  
  234.             insert(siblingNode->getKeyValue(0), ((CLeafNode*)siblingNode)->getData(0));  
  235.             siblingNode->removeKey(0, 0);  
  236.             parentNode->setKeyValue(keyIndex, siblingNode->getKeyValue(0));  
  237.         }  
  238.         break;  
  239.     default:  
  240.         break;  
  241.     }  
  242. }  
  243.   
  244. int CLeafNode::getChildIndex(KeyType key, int keyIndex)const  
  245. {  
  246.     return keyIndex;  
  247. }  
  • BPlus_tree.h
[cpp] view plaincopy
  1. #ifndef BPLUS_TREE_H  
  2. #define BPLUS_TREE_H  
  3.   
  4. #include "BPlus_node.h"  
  5. #include <vector>  
  6. using namespace std;  
  7.   
  8. enum COMPARE_OPERATOR{LT, LE, EQ, BE, BT, BETWEEN}; // 比较操作符:<、<=、=、>=、>、<>  
  9. const int INVALID_INDEX = -1;  
  10.   
  11. struct SelectResult  
  12. {  
  13.     int keyIndex;  
  14.     CLeafNode* targetNode;  
  15. };  
  16.   
  17. class CBPlusTree{  
  18. public:  
  19.     CBPlusTree();  
  20.     ~CBPlusTree();  
  21.     bool insert(KeyType key, const DataType& data);  
  22.     bool remove(KeyType key);  
  23.     bool update(KeyType oldKey, KeyType newKey);  
  24.     // 定值查询,compareOperator可以是LT(<)、LE(<=)、EQ(=)、BE(>=)、BT(>)  
  25.     vector<DataType> select(KeyType compareKey, int compareOpeartor);  
  26.     // 范围查询,BETWEEN  
  27.     vector<DataType> select(KeyType smallKey, KeyType largeKey);  
  28.     bool search(KeyType key); // 查找是否存在  
  29.     void clear();             // 清空  
  30.     void print()const;        // 打印树关键字  
  31.     void printData()const;    // 打印数据  
  32. private:  
  33.     void recursive_insert(CNode* parentNode, KeyType key, const DataType& data);  
  34.     void recursive_remove(CNode* parentNode, KeyType key);  
  35.     void printInConcavo(CNode *pNode, int count)const;  
  36.     bool recursive_search(CNode *pNode, KeyType key)const;  
  37.     void changeKey(CNode *pNode, KeyType oldKey, KeyType newKey);  
  38.     void search(KeyType key, SelectResult& result);  
  39.     void recursive_search(CNode* pNode, KeyType key, SelectResult& result);  
  40.     void remove(KeyType key, DataType& dataValue);  
  41.     void recursive_remove(CNode* parentNode, KeyType key, DataType& dataValue);  
  42. private:  
  43.     CNode* m_Root;  
  44.     CLeafNode* m_DataHead;  
  45.     KeyType m_MaxKey;  // B+树中的最大键  
  46. };  
  47.   
  48. #endif  
  • BPlus_tree.cpp
[cpp] view plaincopy
  1. #include "BPlus_tree.h"  
  2. #include <iostream>  
  3. #include <algorithm>  
  4. using namespace std;  
  5.   
  6. CBPlusTree::CBPlusTree(){  
  7.     m_Root = NULL;  
  8.     m_DataHead = NULL;  
  9. }  
  10.   
  11. CBPlusTree::~CBPlusTree(){  
  12.     clear();  
  13. }  
  14.   
  15. bool CBPlusTree::insert(KeyType key, const DataType& data){  
  16.     // 是否已经存在  
  17.     if (search(key))  
  18.     {  
  19.         return false;  
  20.     }  
  21.     // 找到可以插入的叶子结点,否则创建新的叶子结点  
  22.     if(m_Root==NULL)    
  23.     {  
  24.         m_Root = new CLeafNode();  
  25.         m_DataHead = (CLeafNode*)m_Root;  
  26.         m_MaxKey = key;  
  27.     }  
  28.     if (m_Root->getKeyNum()>=MAXNUM_KEY) // 根结点已满,分裂  
  29.     {  
  30.         CInternalNode* newNode = new CInternalNode();  //创建新的根节点  
  31.         newNode->setChild(0, m_Root);  
  32.         m_Root->split(newNode, 0);    // 叶子结点分裂  
  33.         m_Root = newNode;  //更新根节点指针  
  34.     }  
  35.     if (key>m_MaxKey)  // 更新最大键值  
  36.     {  
  37.         m_MaxKey = key;  
  38.     }  
  39.     recursive_insert(m_Root, key, data);  
  40.     return true;  
  41. }  
  42.   
  43. void CBPlusTree::recursive_insert(CNode* parentNode, KeyType key, const DataType& data)  
  44. {  
  45.     if (parentNode->getType()==LEAF)  // 叶子结点,直接插入  
  46.     {  
  47.         ((CLeafNode*)parentNode)->insert(key, data);  
  48.     }  
  49.     else  
  50.     {  
  51.         // 找到子结点  
  52.         int keyIndex = parentNode->getKeyIndex(key);  
  53.         int childIndex= parentNode->getChildIndex(key, keyIndex); // 孩子结点指针索引  
  54.         CNode* childNode = ((CInternalNode*)parentNode)->getChild(childIndex);  
  55.         if (childNode->getKeyNum()>=MAXNUM_LEAF)  // 子结点已满,需进行分裂  
  56.         {  
  57.             childNode->split(parentNode, childIndex);        
  58.             if (parentNode->getKeyValue(childIndex)<=key)   // 确定目标子结点  
  59.             {  
  60.                 childNode = ((CInternalNode*)parentNode)->getChild(childIndex+1);  
  61.             }  
  62.         }  
  63.         recursive_insert(childNode, key, data);  
  64.     }  
  65. }  
  66.   
  67. void CBPlusTree::clear()  
  68. {  
  69.     if (m_Root!=NULL)  
  70.     {  
  71.         m_Root->clear();  
  72.         delete m_Root;  
  73.         m_Root = NULL;  
  74.         m_DataHead = NULL;  
  75.     }  
  76. }  
  77.   
  78. bool CBPlusTree::search(KeyType key)  
  79. {  
  80.     return recursive_search(m_Root, key);  
  81. }  
  82.   
  83. bool CBPlusTree::recursive_search(CNode *pNode, KeyType key)const  
  84. {  
  85.     if (pNode==NULL)  //检测节点指针是否为空,或该节点是否为叶子节点  
  86.     {  
  87.         return false;  
  88.     }  
  89.     else  
  90.     {  
  91.         int keyIndex = pNode->getKeyIndex(key);  
  92.         int childIndex = pNode->getChildIndex(key, keyIndex); // 孩子结点指针索引  
  93.         if (keyIndex<pNode->getKeyNum() && key==pNode->getKeyValue(keyIndex))  
  94.         {  
  95.             return true;  
  96.         }  
  97.         else  
  98.         {  
  99.             if (pNode->getType()==LEAF)   //检查该节点是否为叶子节点  
  100.             {  
  101.                 return false;  
  102.             }  
  103.             else  
  104.             {  
  105.                 return recursive_search(((CInternalNode*)pNode)->getChild(childIndex), key);  
  106.             }  
  107.         }  
  108.     }  
  109. }  
  110.   
  111. void CBPlusTree::print()const  
  112. {  
  113.     printInConcavo(m_Root, 10);  
  114. }  
  115.   
  116. void CBPlusTree::printInConcavo(CNode *pNode, int count) const{  
  117.     if (pNode!=NULL)  
  118.     {  
  119.         int i, j;  
  120.         for (i=0; i<pNode->getKeyNum(); ++i)  
  121.         {  
  122.             if (pNode->getType()!=LEAF)  
  123.             {  
  124.                 printInConcavo(((CInternalNode*)pNode)->getChild(i), count-2);  
  125.             }  
  126.             for (j=count; j>=0; --j)  
  127.             {  
  128.                 cout<<"-";  
  129.             }  
  130.             cout<<pNode->getKeyValue(i)<<endl;  
  131.         }  
  132.         if (pNode->getType()!=LEAF)  
  133.         {  
  134.             printInConcavo(((CInternalNode*)pNode)->getChild(i), count-2);  
  135.         }  
  136.     }  
  137. }  
  138.   
  139. void CBPlusTree::printData()const  
  140. {  
  141.     CLeafNode* itr = m_DataHead;  
  142.     while(itr!=NULL)  
  143.     {  
  144.         for (int i=0; i<itr->getKeyNum(); ++i)  
  145.         {  
  146.             cout<<itr->getData(i)<<" ";  
  147.         }  
  148.         cout<<endl;  
  149.         itr = itr->getRightSibling();  
  150.     }  
  151. }  
  152.   
  153. bool CBPlusTree::remove(KeyType key)  
  154. {  
  155.     if (!search(key))  //不存在  
  156.     {  
  157.         return false;  
  158.     }  
  159.     if (m_Root->getKeyNum()==1)//特殊情况处理  
  160.     {  
  161.         if (m_Root->getType()==LEAF)  
  162.         {  
  163.             clear();  
  164.             return true;  
  165.         }  
  166.         else  
  167.         {  
  168.             CNode *pChild1 = ((CInternalNode*)m_Root)->getChild(0);  
  169.             CNode *pChild2 = ((CInternalNode*)m_Root)->getChild(1);  
  170.             if (pChild1->getKeyNum()==MINNUM_KEY && pChild2->getKeyNum()==MINNUM_KEY)  
  171.             {  
  172.                 pChild1->mergeChild(m_Root, pChild2, 0);  
  173.                 delete m_Root;  
  174.                 m_Root = pChild1;  
  175.             }  
  176.         }  
  177.     }  
  178.     recursive_remove(m_Root, key);  
  179.     return true;  
  180. }  
  181.   
  182. // parentNode中包含的键值数>MINNUM_KEY  
  183. void CBPlusTree::recursive_remove(CNode* parentNode, KeyType key)  
  184. {  
  185.     int keyIndex = parentNode->getKeyIndex(key);  
  186.     int childIndex= parentNode->getChildIndex(key, keyIndex); // 孩子结点指针索引  
  187.     if (parentNode->getType()==LEAF)// 找到目标叶子节点  
  188.     {  
  189.         if (key==m_MaxKey&&keyIndex>0)  
  190.         {  
  191.             m_MaxKey = parentNode->getKeyValue(keyIndex-1);  
  192.         }  
  193.         parentNode->removeKey(keyIndex, childIndex);  // 直接删除  
  194.         // 如果键值在内部结点中存在,也要相应的替换内部结点  
  195.         if (childIndex==0 && m_Root->getType()!=LEAF && parentNode!=m_DataHead)  
  196.         {  
  197.             changeKey(m_Root, key, parentNode->getKeyValue(0));  
  198.         }  
  199.     }  
  200.     else // 内结点  
  201.     {  
  202.         CNode *pChildNode = ((CInternalNode*)parentNode)->getChild(childIndex); //包含key的子树根节点  
  203.         if (pChildNode->getKeyNum()==MINNUM_KEY)                       // 包含关键字达到下限值,进行相关操作  
  204.         {  
  205.             CNode *pLeft = childIndex>0 ? ((CInternalNode*)parentNode)->getChild(childIndex-1) : NULL;                       //左兄弟节点  
  206.             CNode *pRight = childIndex<parentNode->getKeyNum() ? ((CInternalNode*)parentNode)->getChild(childIndex+1) : NULL;//右兄弟节点  
  207.             // 先考虑从兄弟结点中借  
  208.             if (pLeft && pLeft->getKeyNum()>MINNUM_KEY)// 左兄弟结点可借  
  209.             {  
  210.                 pChildNode->borrowFrom(pLeft, parentNode, childIndex-1, LEFT);  
  211.             }  
  212.             else if (pRight && pRight->getKeyNum()>MINNUM_KEY)//右兄弟结点可借  
  213.             {  
  214.                 pChildNode->borrowFrom(pRight, parentNode, childIndex, RIGHT);  
  215.             }  
  216.             //左右兄弟节点都不可借,考虑合并  
  217.             else if (pLeft)                    //与左兄弟合并  
  218.             {  
  219.                 pLeft->mergeChild(parentNode, pChildNode, childIndex-1);  
  220.                 pChildNode = pLeft;  
  221.             }  
  222.             else if (pRight)                   //与右兄弟合并  
  223.             {  
  224.                 pChildNode->mergeChild(parentNode, pRight, childIndex);  
  225.             }  
  226.         }  
  227.         recursive_remove(pChildNode, key);  
  228.     }  
  229. }  
  230.   
  231. void CBPlusTree::changeKey(CNode *pNode, KeyType oldKey, KeyType newKey)  
  232. {  
  233.     if (pNode!=NULL && pNode->getType()!=LEAF)  
  234.     {  
  235.         int keyIndex = pNode->getKeyIndex(oldKey);  
  236.         if (keyIndex<pNode->getKeyNum() && oldKey==pNode->getKeyValue(keyIndex))  // 找到  
  237.         {  
  238.             pNode->setKeyValue(keyIndex, newKey);  
  239.         }  
  240.         else   // 继续找  
  241.         {  
  242.             changeKey(((CInternalNode*)pNode)->getChild(keyIndex), oldKey, newKey);  
  243.         }  
  244.     }  
  245. }  
  246.   
  247. bool CBPlusTree::update(KeyType oldKey, KeyType newKey)  
  248. {  
  249.     if (search(newKey)) // 检查更新后的键是否已经存在  
  250.     {  
  251.         return false;  
  252.     }  
  253.     else  
  254.     {  
  255.         int dataValue;  
  256.         remove(oldKey, dataValue);  
  257.         if (dataValue==INVALID_INDEX)  
  258.         {  
  259.             return false;  
  260.         }  
  261.         else  
  262.         {  
  263.             return insert(newKey, dataValue);  
  264.         }  
  265.     }  
  266. }  
  267.   
  268. void CBPlusTree::remove(KeyType key, DataType& dataValue)  
  269. {  
  270.     if (!search(key))  //不存在  
  271.     {  
  272.         dataValue = INVALID_INDEX;  
  273.         return;  
  274.     }  
  275.     if (m_Root->getKeyNum()==1)//特殊情况处理  
  276.     {  
  277.         if (m_Root->getType()==LEAF)  
  278.         {  
  279.             dataValue = ((CLeafNode*)m_Root)->getData(0);  
  280.             clear();  
  281.             return;  
  282.         }  
  283.         else  
  284.         {  
  285.             CNode *pChild1 = ((CInternalNode*)m_Root)->getChild(0);  
  286.             CNode *pChild2 = ((CInternalNode*)m_Root)->getChild(1);  
  287.             if (pChild1->getKeyNum()==MINNUM_KEY && pChild2->getKeyNum()==MINNUM_KEY)  
  288.             {  
  289.                 pChild1->mergeChild(m_Root, pChild2, 0);  
  290.                 delete m_Root;  
  291.                 m_Root = pChild1;  
  292.             }  
  293.         }  
  294.     }  
  295.     recursive_remove(m_Root, key, dataValue);  
  296. }  
  297.   
  298. void CBPlusTree::recursive_remove(CNode* parentNode, KeyType key, DataType& dataValue)  
  299. {  
  300.     int keyIndex = parentNode->getKeyIndex(key);  
  301.     int childIndex= parentNode->getChildIndex(key, keyIndex); // 孩子结点指针索引  
  302.     if (parentNode->getType()==LEAF)// 找到目标叶子节点  
  303.     {  
  304.         if (key==m_MaxKey&&keyIndex>0)  
  305.         {  
  306.             m_MaxKey = parentNode->getKeyValue(keyIndex-1);  
  307.         }  
  308.         dataValue = ((CLeafNode*)parentNode)->getData(keyIndex);  
  309.         parentNode->removeKey(keyIndex, childIndex);  // 直接删除  
  310.         // 如果键值在内部结点中存在,也要相应的替换内部结点  
  311.         if (childIndex==0 && m_Root->getType()!=LEAF && parentNode!=m_DataHead)  
  312.         {  
  313.             changeKey(m_Root, key, parentNode->getKeyValue(0));  
  314.         }  
  315.     }  
  316.     else // 内结点  
  317.     {  
  318.         CNode *pChildNode = ((CInternalNode*)parentNode)->getChild(childIndex); //包含key的子树根节点  
  319.         if (pChildNode->getKeyNum()==MINNUM_KEY)                       // 包含关键字达到下限值,进行相关操作  
  320.         {  
  321.             CNode *pLeft = childIndex>0 ? ((CInternalNode*)parentNode)->getChild(childIndex-1) : NULL;                       //左兄弟节点  
  322.             CNode *pRight = childIndex<parentNode->getKeyNum() ? ((CInternalNode*)parentNode)->getChild(childIndex+1) : NULL;//右兄弟节点  
  323.             // 先考虑从兄弟结点中借  
  324.             if (pLeft && pLeft->getKeyNum()>MINNUM_KEY)// 左兄弟结点可借  
  325.             {  
  326.                 pChildNode->borrowFrom(pLeft, parentNode, childIndex-1, LEFT);  
  327.             }  
  328.             else if (pRight && pRight->getKeyNum()>MINNUM_KEY)//右兄弟结点可借  
  329.             {  
  330.                 pChildNode->borrowFrom(pRight, parentNode, childIndex, RIGHT);  
  331.             }  
  332.             //左右兄弟节点都不可借,考虑合并  
  333.             else if (pLeft)                    //与左兄弟合并  
  334.             {  
  335.                 pLeft->mergeChild(parentNode, pChildNode, childIndex-1);  
  336.                 pChildNode = pLeft;  
  337.             }  
  338.             else if (pRight)                   //与右兄弟合并  
  339.             {  
  340.                 pChildNode->mergeChild(parentNode, pRight, childIndex);  
  341.             }  
  342.         }  
  343.         recursive_remove(pChildNode, key, dataValue);  
  344.     }  
  345. }  
  346.   
  347. vector<DataType> CBPlusTree::select(KeyType compareKey, int compareOpeartor)  
  348. {  
  349.     vector<DataType> results;  
  350.     if (m_Root!=NULL)  
  351.     {  
  352.         if (compareKey>m_MaxKey)   // 比较键值大于B+树中最大的键值  
  353.         {  
  354.             if (compareOpeartor==LE || compareOpeartor==LT)  
  355.             {  
  356.                 for(CLeafNode* itr = m_DataHead; itr!=NULL; itr= itr->getRightSibling())  
  357.                 {  
  358.                     for (int i=0; i<itr->getKeyNum(); ++i)  
  359.                     {  
  360.                         results.push_back(itr->getData(i));  
  361.                     }  
  362.                 }  
  363.             }  
  364.         }  
  365.         else if (compareKey<m_DataHead->getKeyValue(0))  // 比较键值小于B+树中最小的键值  
  366.         {  
  367.             if (compareOpeartor==BE || compareOpeartor==BT)  
  368.             {  
  369.                 for(CLeafNode* itr = m_DataHead; itr!=NULL; itr= itr->getRightSibling())  
  370.                 {  
  371.                     for (int i=0; i<itr->getKeyNum(); ++i)  
  372.                     {  
  373.                         results.push_back(itr->getData(i));  
  374.                     }  
  375.                 }  
  376.             }  
  377.         }  
  378.         else  // 比较键值在B+树中  
  379.         {  
  380.             SelectResult result;  
  381.             search(compareKey, result);  
  382.             switch(compareOpeartor)  
  383.             {  
  384.             case LT:  
  385.             case LE:  
  386.                 {  
  387.                     CLeafNode* itr = m_DataHead;  
  388.                     int i;  
  389.                     while (itr!=result.targetNode)  
  390.                     {  
  391.                         for (i=0; i<itr->getKeyNum(); ++i)  
  392.                         {  
  393.                             results.push_back(itr->getData(i));  
  394.                         }  
  395.                         itr = itr->getRightSibling();  
  396.                     }  
  397.                     for (i=0; i<result.keyIndex; ++i)  
  398.                     {  
  399.                         results.push_back(itr->getData(i));  
  400.                     }  
  401.                     if (itr->getKeyValue(i)<compareKey ||   
  402.                         (compareOpeartor==LE && compareKey==itr->getKeyValue(i)))  
  403.                     {  
  404.                         results.push_back(itr->getData(i));  
  405.                     }  
  406.                 }  
  407.                 break;  
  408.             case EQ:  
  409.                 {  
  410.                     if (result.targetNode->getKeyValue(result.keyIndex)==compareKey)  
  411.                     {  
  412.                         results.push_back(result.targetNode->getData(result.keyIndex));  
  413.                     }  
  414.                 }  
  415.                 break;  
  416.             case BE:  
  417.             case BT:  
  418.                 {  
  419.                     CLeafNode* itr = result.targetNode;  
  420.                     if (compareKey<itr->getKeyValue(result.keyIndex) ||  
  421.                         (compareOpeartor==BE && compareKey==itr->getKeyValue(result.keyIndex))  
  422.                         )  
  423.                     {  
  424.                         results.push_back(itr->getData(result.keyIndex));  
  425.                     }  
  426.                     int i;  
  427.                     for (i=result.keyIndex+1; i<itr->getKeyNum(); ++i)  
  428.                     {  
  429.                         results.push_back(itr->getData(i));  
  430.                     }  
  431.                     itr = itr->getRightSibling();  
  432.                     while (itr!=NULL)  
  433.                     {  
  434.                         for (i=0; i<itr->getKeyNum(); ++i)  
  435.                         {  
  436.                             results.push_back(itr->getData(i));  
  437.                         }  
  438.                         itr = itr->getRightSibling();  
  439.                     }  
  440.                 }  
  441.                 break;  
  442.             default:  // 范围查询  
  443.                 break;  
  444.             }  
  445.         }  
  446.     }  
  447.     sort<vector<DataType>::iterator>(results.begin(), results.end());  
  448.     return results;  
  449. }  
  450.   
  451. vector<DataType> CBPlusTree::select(KeyType smallKey, KeyType largeKey)  
  452. {  
  453.     vector<DataType> results;  
  454.     if (smallKey<=largeKey)  
  455.     {  
  456.         SelectResult start, end;  
  457.         search(smallKey, start);  
  458.         search(largeKey, end);  
  459.         CLeafNode* itr = start.targetNode;  
  460.         int i = start.keyIndex;  
  461.         if (itr->getKeyValue(i)<smallKey)  
  462.         {  
  463.             ++i;  
  464.         }  
  465.         if (end.targetNode->getKeyValue(end.keyIndex)>largeKey)  
  466.         {  
  467.             --end.keyIndex;  
  468.         }  
  469.         while (itr!=end.targetNode)  
  470.         {  
  471.             for (; i<itr->getKeyNum(); ++i)  
  472.             {  
  473.                 results.push_back(itr->getData(i));  
  474.             }  
  475.             itr = itr->getRightSibling();  
  476.             i = 0;  
  477.         }  
  478.         for (; i<=end.keyIndex; ++i)  
  479.         {  
  480.             results.push_back(itr->getData(i));  
  481.         }  
  482.     }  
  483.     sort<vector<DataType>::iterator>(results.begin(), results.end());  
  484.     return results;  
  485. }  
  486.   
  487. void CBPlusTree::search(KeyType key, SelectResult& result)  
  488. {  
  489.     recursive_search(m_Root, key, result);  
  490. }  
  491.   
  492. void CBPlusTree::recursive_search(CNode* pNode, KeyType key, SelectResult& result)  
  493. {  
  494.     int keyIndex = pNode->getKeyIndex(key);  
  495.     int childIndex = pNode->getChildIndex(key, keyIndex); // 孩子结点指针索引  
  496.     if (pNode->getType()==LEAF)  
  497.     {  
  498.         result.keyIndex = keyIndex;  
  499.         result.targetNode = (CLeafNode*)pNode;  
  500.         return;  
  501.     }  
  502.     else  
  503.     {  
  504.         return recursive_search(((CInternalNode*)pNode)->getChild(childIndex), key, result);  
  505.     }  

  1. }
原文来自:http://blog.csdn.net/liu1064782986/article/details/7982290

0 0