B+树(C++实现)
定义:
一棵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.叶子结点的关键字个数可以单独设置,一般和内结点关键字个数相同。
一图胜千言(图片来源:维基百科):
实现
- BPlus_node.h
#ifndef BPLUS_NODE #define BPLUS_NODE #define NULL 0 enum NODE_TYPE{INTERNAL, LEAF}; // 结点类型:内结点、叶子结点 enum SIBLING_DIRECTION{LEFT, RIGHT}; // 兄弟结点方向:左兄弟结点、右兄弟结点 typedef float KeyType; // 键类型 typedef int DataType; // 值类型 const int ORDER = 7; // B+树的阶(非根内结点的最小子树个数) const int MINNUM_KEY = ORDER-1; // 最小键值个数 const int MAXNUM_KEY = 2*ORDER-1; // 最大键值个数 const int MINNUM_CHILD = MINNUM_KEY+1; // 最小子树个数 const int MAXNUM_CHILD = MAXNUM_KEY+1; // 最大子树个数 const int MINNUM_LEAF = MINNUM_KEY; // 最小叶子结点键值个数 const int MAXNUM_LEAF = MAXNUM_KEY; // 最大叶子结点键值个数 // 结点基类 class CNode{ public: CNode(); virtual ~CNode(); NODE_TYPE getType() const {return m_Type;} void setType(NODE_TYPE type){m_Type = type;} int getKeyNum() const {return m_KeyNum;} void setKeyNum(int n){m_KeyNum = n;} KeyType getKeyValue(int i) const {return m_KeyValues[i];} void setKeyValue(int i, KeyType key){m_KeyValues[i] = key;} int getKeyIndex(KeyType key)const; // 找到键值在结点中存储的下标 // 纯虚函数,定义接口 virtual void removeKey(int keyIndex, int childIndex)=0; // 从结点中移除键值 virtual void split(CNode* parentNode, int childIndex)=0; // 分裂结点 virtual void mergeChild(CNode* parentNode, CNode* childNode, int keyIndex)=0; // 合并结点 virtual void clear()=0; // 清空结点,同时会清空结点所包含的子树结点 virtual void borrowFrom(CNode* destNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d)=0; // 从兄弟结点中借一个键值 virtual int getChildIndex(KeyType key, int keyIndex)const=0; // 根据键值获取孩子结点指针下标 protected: NODE_TYPE m_Type; int m_KeyNum; KeyType m_KeyValues[MAXNUM_KEY]; }; // 内结点 class CInternalNode : public CNode{ public: CInternalNode(); virtual ~CInternalNode(); CNode* getChild(int i) const {return m_Childs[i];} void setChild(int i, CNode* child){m_Childs[i] = child;} void insert(int keyIndex, int childIndex, KeyType key, CNode* childNode); virtual void split(CNode* parentNode, int childIndex); virtual void mergeChild(CNode* parentNode, CNode* childNode, int keyIndex); virtual void removeKey(int keyIndex, int childIndex); virtual void clear(); virtual void borrowFrom(CNode* destNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d); virtual int getChildIndex(KeyType key, int keyIndex)const; private: CNode* m_Childs[MAXNUM_CHILD]; }; // 叶子结点 class CLeafNode : public CNode{ public: CLeafNode(); virtual ~CLeafNode(); CLeafNode* getLeftSibling() const {return m_LeftSibling;} void setLeftSibling(CLeafNode* node){m_LeftSibling = node;} CLeafNode* getRightSibling() const {return m_RightSibling;} void setRightSibling(CLeafNode* node){m_RightSibling = node;} DataType getData(int i) const {return m_Datas[i];} void setData(int i, const DataType& data){m_Datas[i] = data;} void insert(KeyType key, const DataType& data); virtual void split(CNode* parentNode, int childIndex); virtual void mergeChild(CNode* parentNode, CNode* childNode, int keyIndex); virtual void removeKey(int keyIndex, int childIndex); virtual void clear(); virtual void borrowFrom(CNode* destNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d); virtual int getChildIndex(KeyType key, int keyIndex)const; private: CLeafNode* m_LeftSibling; CLeafNode* m_RightSibling; DataType m_Datas[MAXNUM_LEAF]; }; #endif
- BPlus_node.cpp
#include "BPlus_node.h" // CNode CNode::CNode(){ setType(LEAF); setKeyNum(0); } CNode::~CNode(){ setKeyNum(0); } int CNode::getKeyIndex(KeyType key)const { int left = 0; int right = getKeyNum()-1; int current; while(left!=right) { current = (left+right)/2; KeyType currentKey = getKeyValue(current); if (key>currentKey) { left = current+1; } else { right = current; } } return left; } // CInternalNode CInternalNode::CInternalNode():CNode(){ setType(INTERNAL); } CInternalNode::~CInternalNode(){ } void CInternalNode::clear() { for (int i=0; i<=m_KeyNum; ++i) { m_Childs[i]->clear(); delete m_Childs[i]; m_Childs[i] = NULL; } } void CInternalNode::split(CNode* parentNode, int childIndex) { CInternalNode* newNode = new CInternalNode();//分裂后的右节点 newNode->setKeyNum(MINNUM_KEY); int i; for (i=0; i<MINNUM_KEY; ++i)// 拷贝关键字的值 { newNode->setKeyValue(i, m_KeyValues[i+MINNUM_CHILD]); } for (i=0; i<MINNUM_CHILD; ++i) // 拷贝孩子节点指针 { newNode->setChild(i, m_Childs[i+MINNUM_CHILD]); } setKeyNum(MINNUM_KEY); //更新左子树的关键字个数 ((CInternalNode*)parentNode)->insert(childIndex, childIndex+1, m_KeyValues[MINNUM_KEY], newNode); } void CInternalNode::insert(int keyIndex, int childIndex, KeyType key, CNode* childNode){ int i; for (i=getKeyNum(); i>keyIndex; --i)//将父节点中的childIndex后的所有关键字的值和子树指针向后移一位 { setChild(i+1,m_Childs[i]); setKeyValue(i,m_KeyValues[i-1]); } if (i==childIndex) { setChild(i+1, m_Childs[i]); } setChild(childIndex, childNode); setKeyValue(keyIndex, key); setKeyNum(m_KeyNum+1); } void CInternalNode::mergeChild(CNode* parentNode, CNode* childNode, int keyIndex) { // 合并数据 insert(MINNUM_KEY, MINNUM_KEY+1, parentNode->getKeyValue(keyIndex), ((CInternalNode*)childNode)->getChild(0)); int i; for (i=1; i<=childNode->getKeyNum(); ++i) { insert(MINNUM_KEY+i, MINNUM_KEY+i+1, childNode->getKeyValue(i-1), ((CInternalNode*)childNode)->getChild(i)); } //父节点删除index的key parentNode->removeKey(keyIndex, keyIndex+1); delete ((CInternalNode*)parentNode)->getChild(keyIndex+1); } void CInternalNode::removeKey(int keyIndex, int childIndex) { for (int i=0; i<getKeyNum()-keyIndex-1; ++i) { setKeyValue(keyIndex+i, getKeyValue(keyIndex+i+1)); setChild(childIndex+i, getChild(childIndex+i+1)); } setKeyNum(getKeyNum()-1); } void CInternalNode::borrowFrom(CNode* siblingNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d) { switch(d) { case LEFT: // 从左兄弟结点借 { insert(0, 0, parentNode->getKeyValue(keyIndex), ((CInternalNode*)siblingNode)->getChild(siblingNode->getKeyNum())); parentNode->setKeyValue(keyIndex, siblingNode->getKeyValue(siblingNode->getKeyNum()-1)); siblingNode->removeKey(siblingNode->getKeyNum()-1, siblingNode->getKeyNum()); } break; case RIGHT: // 从右兄弟结点借 { insert(getKeyNum(), getKeyNum()+1, parentNode->getKeyValue(keyIndex), ((CInternalNode*)siblingNode)->getChild(0)); parentNode->setKeyValue(keyIndex, siblingNode->getKeyValue(0)); siblingNode->removeKey(0, 0); } break; default: break; } } int CInternalNode::getChildIndex(KeyType key, int keyIndex)const { if (key==getKeyValue(keyIndex)) { return keyIndex+1; } else { return keyIndex; } } // CLeafNode CLeafNode::CLeafNode():CNode(){ setType(LEAF); setLeftSibling(NULL); setRightSibling(NULL); } CLeafNode::~CLeafNode(){ } void CLeafNode::clear() { for (int i=0; i<m_KeyNum; ++i) { // if type of m_Datas is pointer //delete m_Datas[i]; //m_Datas[i] = NULL; } } void CLeafNode::insert(KeyType key, const DataType& data) { int i; for (i=m_KeyNum; i>=1 && m_KeyValues[i-1]>key; --i) { setKeyValue(i, m_KeyValues[i-1]); setData(i, m_Datas[i-1]); } setKeyValue(i, key); setData(i, data); setKeyNum(m_KeyNum+1); } void CLeafNode::split(CNode* parentNode, int childIndex) { CLeafNode* newNode = new CLeafNode();//分裂后的右节点 setKeyNum(MINNUM_LEAF); newNode->setKeyNum(MINNUM_LEAF+1); newNode->setRightSibling(getRightSibling()); setRightSibling(newNode); newNode->setLeftSibling(this); int i; for (i=0; i<MINNUM_LEAF+1; ++i)// 拷贝关键字的值 { newNode->setKeyValue(i, m_KeyValues[i+MINNUM_LEAF]); } for (i=0; i<MINNUM_LEAF+1; ++i)// 拷贝数据 { newNode->setData(i, m_Datas[i+MINNUM_LEAF]); } ((CInternalNode*)parentNode)->insert(childIndex, childIndex+1, m_KeyValues[MINNUM_LEAF], newNode); } void CLeafNode::mergeChild(CNode* parentNode, CNode* childNode, int keyIndex) { // 合并数据 for (int i=0; i<childNode->getKeyNum(); ++i) { insert(childNode->getKeyValue(i), ((CLeafNode*)childNode)->getData(i)); } setRightSibling(((CLeafNode*)childNode)->getRightSibling()); //父节点删除index的key, parentNode->removeKey(keyIndex, keyIndex+1); } void CLeafNode::removeKey(int keyIndex, int childIndex) { for (int i=keyIndex; i<getKeyNum()-1; ++i) { setKeyValue(i, getKeyValue(i+1)); setData(i, getData(i+1)); } setKeyNum(getKeyNum()-1); } void CLeafNode::borrowFrom(CNode* siblingNode, CNode* parentNode, int keyIndex, SIBLING_DIRECTION d) { switch(d) { case LEFT: // 从左兄弟结点借 { insert(siblingNode->getKeyValue(siblingNode->getKeyNum()-1), ((CLeafNode*)siblingNode)->getData(siblingNode->getKeyNum()-1)); siblingNode->removeKey(siblingNode->getKeyNum()-1, siblingNode->getKeyNum()-1); parentNode->setKeyValue(keyIndex, getKeyValue(0)); } break; case RIGHT: // 从右兄弟结点借 { insert(siblingNode->getKeyValue(0), ((CLeafNode*)siblingNode)->getData(0)); siblingNode->removeKey(0, 0); parentNode->setKeyValue(keyIndex, siblingNode->getKeyValue(0)); } break; default: break; } } int CLeafNode::getChildIndex(KeyType key, int keyIndex)const { return keyIndex; }
- BPlus_tree.h
#ifndef BPLUS_TREE_H #define BPLUS_TREE_H #include "BPlus_node.h" #include <vector> using namespace std; enum COMPARE_OPERATOR{LT, LE, EQ, BE, BT, BETWEEN}; // 比较操作符:<、<=、=、>=、>、<> const int INVALID_INDEX = -1; struct SelectResult { int keyIndex; CLeafNode* targetNode; }; class CBPlusTree{ public: CBPlusTree(); ~CBPlusTree(); bool insert(KeyType key, const DataType& data); bool remove(KeyType key); bool update(KeyType oldKey, KeyType newKey); // 定值查询,compareOperator可以是LT(<)、LE(<=)、EQ(=)、BE(>=)、BT(>) vector<DataType> select(KeyType compareKey, int compareOpeartor); // 范围查询,BETWEEN vector<DataType> select(KeyType smallKey, KeyType largeKey); bool search(KeyType key); // 查找是否存在 void clear(); // 清空 void print()const; // 打印树关键字 void printData()const; // 打印数据 private: void recursive_insert(CNode* parentNode, KeyType key, const DataType& data); void recursive_remove(CNode* parentNode, KeyType key); void printInConcavo(CNode *pNode, int count)const; bool recursive_search(CNode *pNode, KeyType key)const; void changeKey(CNode *pNode, KeyType oldKey, KeyType newKey); void search(KeyType key, SelectResult& result); void recursive_search(CNode* pNode, KeyType key, SelectResult& result); void remove(KeyType key, DataType& dataValue); void recursive_remove(CNode* parentNode, KeyType key, DataType& dataValue); private: CNode* m_Root; CLeafNode* m_DataHead; KeyType m_MaxKey; // B+树中的最大键 }; #endif
- BPlus_tree.cpp
#include "BPlus_tree.h" #include <iostream> #include <algorithm> using namespace std; CBPlusTree::CBPlusTree(){ m_Root = NULL; m_DataHead = NULL; } CBPlusTree::~CBPlusTree(){ clear(); } bool CBPlusTree::insert(KeyType key, const DataType& data){ // 是否已经存在 if (search(key)) { return false; } // 找到可以插入的叶子结点,否则创建新的叶子结点 if(m_Root==NULL) { m_Root = new CLeafNode(); m_DataHead = (CLeafNode*)m_Root; m_MaxKey = key; } if (m_Root->getKeyNum()>=MAXNUM_KEY) // 根结点已满,分裂 { CInternalNode* newNode = new CInternalNode(); //创建新的根节点 newNode->setChild(0, m_Root); m_Root->split(newNode, 0); // 叶子结点分裂 m_Root = newNode; //更新根节点指针 } if (key>m_MaxKey) // 更新最大键值 { m_MaxKey = key; } recursive_insert(m_Root, key, data); return true; } void CBPlusTree::recursive_insert(CNode* parentNode, KeyType key, const DataType& data) { if (parentNode->getType()==LEAF) // 叶子结点,直接插入 { ((CLeafNode*)parentNode)->insert(key, data); } else { // 找到子结点 int keyIndex = parentNode->getKeyIndex(key); int childIndex= parentNode->getChildIndex(key, keyIndex); // 孩子结点指针索引 CNode* childNode = ((CInternalNode*)parentNode)->getChild(childIndex); if (childNode->getKeyNum()>=MAXNUM_LEAF) // 子结点已满,需进行分裂 { childNode->split(parentNode, childIndex); if (parentNode->getKeyValue(childIndex)<=key) // 确定目标子结点 { childNode = ((CInternalNode*)parentNode)->getChild(childIndex+1); } } recursive_insert(childNode, key, data); } } void CBPlusTree::clear() { if (m_Root!=NULL) { m_Root->clear(); delete m_Root; m_Root = NULL; m_DataHead = NULL; } } bool CBPlusTree::search(KeyType key) { return recursive_search(m_Root, key); } bool CBPlusTree::recursive_search(CNode *pNode, KeyType key)const { if (pNode==NULL) //检测节点指针是否为空,或该节点是否为叶子节点 { return false; } else { int keyIndex = pNode->getKeyIndex(key); int childIndex = pNode->getChildIndex(key, keyIndex); // 孩子结点指针索引 if (keyIndex<pNode->getKeyNum() && key==pNode->getKeyValue(keyIndex)) { return true; } else { if (pNode->getType()==LEAF) //检查该节点是否为叶子节点 { return false; } else { return recursive_search(((CInternalNode*)pNode)->getChild(childIndex), key); } } } } void CBPlusTree::print()const { printInConcavo(m_Root, 10); } void CBPlusTree::printInConcavo(CNode *pNode, int count) const{ if (pNode!=NULL) { int i, j; for (i=0; i<pNode->getKeyNum(); ++i) { if (pNode->getType()!=LEAF) { printInConcavo(((CInternalNode*)pNode)->getChild(i), count-2); } for (j=count; j>=0; --j) { cout<<"-"; } cout<<pNode->getKeyValue(i)<<endl; } if (pNode->getType()!=LEAF) { printInConcavo(((CInternalNode*)pNode)->getChild(i), count-2); } } } void CBPlusTree::printData()const { CLeafNode* itr = m_DataHead; while(itr!=NULL) { for (int i=0; i<itr->getKeyNum(); ++i) { cout<<itr->getData(i)<<" "; } cout<<endl; itr = itr->getRightSibling(); } } bool CBPlusTree::remove(KeyType key) { if (!search(key)) //不存在 { return false; } if (m_Root->getKeyNum()==1)//特殊情况处理 { if (m_Root->getType()==LEAF) { clear(); return true; } else { CNode *pChild1 = ((CInternalNode*)m_Root)->getChild(0); CNode *pChild2 = ((CInternalNode*)m_Root)->getChild(1); if (pChild1->getKeyNum()==MINNUM_KEY && pChild2->getKeyNum()==MINNUM_KEY) { pChild1->mergeChild(m_Root, pChild2, 0); delete m_Root; m_Root = pChild1; } } } recursive_remove(m_Root, key); return true; } // parentNode中包含的键值数>MINNUM_KEY void CBPlusTree::recursive_remove(CNode* parentNode, KeyType key) { int keyIndex = parentNode->getKeyIndex(key); int childIndex= parentNode->getChildIndex(key, keyIndex); // 孩子结点指针索引 if (parentNode->getType()==LEAF)// 找到目标叶子节点 { if (key==m_MaxKey&&keyIndex>0) { m_MaxKey = parentNode->getKeyValue(keyIndex-1); } parentNode->removeKey(keyIndex, childIndex); // 直接删除 // 如果键值在内部结点中存在,也要相应的替换内部结点 if (childIndex==0 && m_Root->getType()!=LEAF && parentNode!=m_DataHead) { changeKey(m_Root, key, parentNode->getKeyValue(0)); } } else // 内结点 { CNode *pChildNode = ((CInternalNode*)parentNode)->getChild(childIndex); //包含key的子树根节点 if (pChildNode->getKeyNum()==MINNUM_KEY) // 包含关键字达到下限值,进行相关操作 { CNode *pLeft = childIndex>0 ? ((CInternalNode*)parentNode)->getChild(childIndex-1) : NULL; //左兄弟节点 CNode *pRight = childIndex<parentNode->getKeyNum() ? ((CInternalNode*)parentNode)->getChild(childIndex+1) : NULL;//右兄弟节点 // 先考虑从兄弟结点中借 if (pLeft && pLeft->getKeyNum()>MINNUM_KEY)// 左兄弟结点可借 { pChildNode->borrowFrom(pLeft, parentNode, childIndex-1, LEFT); } else if (pRight && pRight->getKeyNum()>MINNUM_KEY)//右兄弟结点可借 { pChildNode->borrowFrom(pRight, parentNode, childIndex, RIGHT); } //左右兄弟节点都不可借,考虑合并 else if (pLeft) //与左兄弟合并 { pLeft->mergeChild(parentNode, pChildNode, childIndex-1); pChildNode = pLeft; } else if (pRight) //与右兄弟合并 { pChildNode->mergeChild(parentNode, pRight, childIndex); } } recursive_remove(pChildNode, key); } } void CBPlusTree::changeKey(CNode *pNode, KeyType oldKey, KeyType newKey) { if (pNode!=NULL && pNode->getType()!=LEAF) { int keyIndex = pNode->getKeyIndex(oldKey); if (keyIndex<pNode->getKeyNum() && oldKey==pNode->getKeyValue(keyIndex)) // 找到 { pNode->setKeyValue(keyIndex, newKey); } else // 继续找 { changeKey(((CInternalNode*)pNode)->getChild(keyIndex), oldKey, newKey); } } } bool CBPlusTree::update(KeyType oldKey, KeyType newKey) { if (search(newKey)) // 检查更新后的键是否已经存在 { return false; } else { int dataValue; remove(oldKey, dataValue); if (dataValue==INVALID_INDEX) { return false; } else { return insert(newKey, dataValue); } } } void CBPlusTree::remove(KeyType key, DataType& dataValue) { if (!search(key)) //不存在 { dataValue = INVALID_INDEX; return; } if (m_Root->getKeyNum()==1)//特殊情况处理 { if (m_Root->getType()==LEAF) { dataValue = ((CLeafNode*)m_Root)->getData(0); clear(); return; } else { CNode *pChild1 = ((CInternalNode*)m_Root)->getChild(0); CNode *pChild2 = ((CInternalNode*)m_Root)->getChild(1); if (pChild1->getKeyNum()==MINNUM_KEY && pChild2->getKeyNum()==MINNUM_KEY) { pChild1->mergeChild(m_Root, pChild2, 0); delete m_Root; m_Root = pChild1; } } } recursive_remove(m_Root, key, dataValue); } void CBPlusTree::recursive_remove(CNode* parentNode, KeyType key, DataType& dataValue) { int keyIndex = parentNode->getKeyIndex(key); int childIndex= parentNode->getChildIndex(key, keyIndex); // 孩子结点指针索引 if (parentNode->getType()==LEAF)// 找到目标叶子节点 { if (key==m_MaxKey&&keyIndex>0) { m_MaxKey = parentNode->getKeyValue(keyIndex-1); } dataValue = ((CLeafNode*)parentNode)->getData(keyIndex); parentNode->removeKey(keyIndex, childIndex); // 直接删除 // 如果键值在内部结点中存在,也要相应的替换内部结点 if (childIndex==0 && m_Root->getType()!=LEAF && parentNode!=m_DataHead) { changeKey(m_Root, key, parentNode->getKeyValue(0)); } } else // 内结点 { CNode *pChildNode = ((CInternalNode*)parentNode)->getChild(childIndex); //包含key的子树根节点 if (pChildNode->getKeyNum()==MINNUM_KEY) // 包含关键字达到下限值,进行相关操作 { CNode *pLeft = childIndex>0 ? ((CInternalNode*)parentNode)->getChild(childIndex-1) : NULL; //左兄弟节点 CNode *pRight = childIndex<parentNode->getKeyNum() ? ((CInternalNode*)parentNode)->getChild(childIndex+1) : NULL;//右兄弟节点 // 先考虑从兄弟结点中借 if (pLeft && pLeft->getKeyNum()>MINNUM_KEY)// 左兄弟结点可借 { pChildNode->borrowFrom(pLeft, parentNode, childIndex-1, LEFT); } else if (pRight && pRight->getKeyNum()>MINNUM_KEY)//右兄弟结点可借 { pChildNode->borrowFrom(pRight, parentNode, childIndex, RIGHT); } //左右兄弟节点都不可借,考虑合并 else if (pLeft) //与左兄弟合并 { pLeft->mergeChild(parentNode, pChildNode, childIndex-1); pChildNode = pLeft; } else if (pRight) //与右兄弟合并 { pChildNode->mergeChild(parentNode, pRight, childIndex); } } recursive_remove(pChildNode, key, dataValue); } } vector<DataType> CBPlusTree::select(KeyType compareKey, int compareOpeartor) { vector<DataType> results; if (m_Root!=NULL) { if (compareKey>m_MaxKey) // 比较键值大于B+树中最大的键值 { if (compareOpeartor==LE || compareOpeartor==LT) { for(CLeafNode* itr = m_DataHead; itr!=NULL; itr= itr->getRightSibling()) { for (int i=0; i<itr->getKeyNum(); ++i) { results.push_back(itr->getData(i)); } } } } else if (compareKey<m_DataHead->getKeyValue(0)) // 比较键值小于B+树中最小的键值 { if (compareOpeartor==BE || compareOpeartor==BT) { for(CLeafNode* itr = m_DataHead; itr!=NULL; itr= itr->getRightSibling()) { for (int i=0; i<itr->getKeyNum(); ++i) { results.push_back(itr->getData(i)); } } } } else // 比较键值在B+树中 { SelectResult result; search(compareKey, result); switch(compareOpeartor) { case LT: case LE: { CLeafNode* itr = m_DataHead; int i; while (itr!=result.targetNode) { for (i=0; i<itr->getKeyNum(); ++i) { results.push_back(itr->getData(i)); } itr = itr->getRightSibling(); } for (i=0; i<result.keyIndex; ++i) { results.push_back(itr->getData(i)); } if (itr->getKeyValue(i)<compareKey || (compareOpeartor==LE && compareKey==itr->getKeyValue(i))) { results.push_back(itr->getData(i)); } } break; case EQ: { if (result.targetNode->getKeyValue(result.keyIndex)==compareKey) { results.push_back(result.targetNode->getData(result.keyIndex)); } } break; case BE: case BT: { CLeafNode* itr = result.targetNode; if (compareKey<itr->getKeyValue(result.keyIndex) || (compareOpeartor==BE && compareKey==itr->getKeyValue(result.keyIndex)) ) { results.push_back(itr->getData(result.keyIndex)); } int i; for (i=result.keyIndex+1; i<itr->getKeyNum(); ++i) { results.push_back(itr->getData(i)); } itr = itr->getRightSibling(); while (itr!=NULL) { for (i=0; i<itr->getKeyNum(); ++i) { results.push_back(itr->getData(i)); } itr = itr->getRightSibling(); } } break; default: // 范围查询 break; } } } sort<vector<DataType>::iterator>(results.begin(), results.end()); return results; } vector<DataType> CBPlusTree::select(KeyType smallKey, KeyType largeKey) { vector<DataType> results; if (smallKey<=largeKey) { SelectResult start, end; search(smallKey, start); search(largeKey, end); CLeafNode* itr = start.targetNode; int i = start.keyIndex; if (itr->getKeyValue(i)<smallKey) { ++i; } if (end.targetNode->getKeyValue(end.keyIndex)>largeKey) { --end.keyIndex; } while (itr!=end.targetNode) { for (; i<itr->getKeyNum(); ++i) { results.push_back(itr->getData(i)); } itr = itr->getRightSibling(); i = 0; } for (; i<=end.keyIndex; ++i) { results.push_back(itr->getData(i)); } } sort<vector<DataType>::iterator>(results.begin(), results.end()); return results; } void CBPlusTree::search(KeyType key, SelectResult& result) { recursive_search(m_Root, key, result); } void CBPlusTree::recursive_search(CNode* pNode, KeyType key, SelectResult& result) { int keyIndex = pNode->getKeyIndex(key); int childIndex = pNode->getChildIndex(key, keyIndex); // 孩子结点指针索引 if (pNode->getType()==LEAF) { result.keyIndex = keyIndex; result.targetNode = (CLeafNode*)pNode; return; } else { return recursive_search(((CInternalNode*)pNode)->getChild(childIndex), key, result); } }