?? cmxbtree.cpp
字號(hào):
}
}
if( i > 0 ) //看看左邊的兄弟
{
if ( i == 1)
pDataLeaf = (BTREE_DATA_LEAF *)pSearchIndexLeaf->pLeafLeft;
else
pDataLeaf = (BTREE_DATA_LEAF *)pSearchIndexLeaf->IndexKeys[i-2].pKeyRight;
if ( ! pDataLeaf ) return -1;
nDataLeafLoc2 = GetTotalElemInDataLeaf( pDataLeaf );
if( nDataLeafLoc1 + nDataLeafLoc2 <= BTREE_DEGREE )
{
if( nIndexLeafLoc == 1) //父節(jié)點(diǎn)只有最后一個(gè)元素
{
DATA_CONTAINER* pTmp[BTREE_DEGREE];
memcpy( pTmp, pSearchDataLeaf->pDataCont, nDataLeafLoc1*sizeof(DATA_CONTAINER*));
memcpy( pSearchDataLeaf->pDataCont,
pDataLeaf->pDataCont, nDataLeafLoc2*sizeof(DATA_CONTAINER*));
memcpy( &pSearchDataLeaf->pDataCont[nDataLeafLoc2],
pTmp, nDataLeafLoc1*sizeof(DATA_CONTAINER*));
pSearchIndexLeaf->IndexKeys[i-1].pKey = pSearchDataLeaf->pDataCont[0]->pData;
pSearchIndexLeaf->pLeafLeft = NULL;
DeleteDataLeaf( pDataLeaf );
return 0;
}
else
{
//可以聯(lián)合
memcpy( &pDataLeaf->pDataCont[nDataLeafLoc2],
pSearchDataLeaf->pDataCont, nDataLeafLoc1*sizeof(DATA_CONTAINER*));
DeleteDataLeaf( pSearchDataLeaf );
if( RemoveIndexKey( pSearchIndexLeaf, i-1 ) < 0 ) return -1;
return 0;
}
}
}
//如果不能聯(lián)合,就開(kāi)始旋轉(zhuǎn)
if ( i > 0 ) //看看左邊的數(shù)據(jù)葉
{
if ( i == 1)
pDataLeaf = (BTREE_DATA_LEAF *)pSearchIndexLeaf->pLeafLeft;
else
pDataLeaf = (BTREE_DATA_LEAF *)pSearchIndexLeaf->IndexKeys[i-2].pKeyRight;
int nDataLeafLoc;
if ( ! pDataLeaf ) return -1;
nDataLeafLoc = GetTotalElemInDataLeaf( pDataLeaf );
//左邊的兄弟有沒(méi)有多余的
if ( nDataLeafLoc > BTREE_DEGREE/2 )
{
for( j = 0; j < nDataLeafLoc1; j++)
pSearchDataLeaf->pDataCont[j+1] = pSearchDataLeaf->pDataCont[j];
pSearchDataLeaf->pDataCont[0] = pDataLeaf->pDataCont[nDataLeafLoc-1];
pDataLeaf->pDataCont[nDataLeafLoc-1] = NULL;
pSearchIndexLeaf->IndexKeys[i-1].pKey =pSearchDataLeaf->pDataCont[0]->pData;
return 0;
}
}
if ( i < BTREE_DEGREE ) //看看右邊的數(shù)據(jù)葉
{
if ( pSearchIndexLeaf->IndexKeys[i].pKey )
{
pDataLeaf = (BTREE_DATA_LEAF *)pSearchIndexLeaf->IndexKeys[i].pKeyRight;
if ( ! pDataLeaf ) return -1;
int nDataLeafLoc = GetTotalElemInDataLeaf( pDataLeaf );
//右邊的兄弟有空
if ( nDataLeafLoc > BTREE_DEGREE/2 )
{
pSearchDataLeaf->pDataCont[nDataLeafLoc1] = pDataLeaf->pDataCont[0];
int j;
for ( j = 0; j < nDataLeafLoc-1; j++)
pDataLeaf->pDataCont[j] = pDataLeaf->pDataCont[j+1];
pDataLeaf->pDataCont[nDataLeafLoc-1] = NULL;
pSearchIndexLeaf->IndexKeys[i].pKey = pDataLeaf->pDataCont[0]->pData;
return 0;
}
}
}
return -1;
}
//向B+Tree 中插入 Key
template <class RECTYPE>
int CMXBTree<RECTYPE>::InsertKey( RECTYPE & Key )
{
//搜索中當(dāng)前的索引葉
BTREE_INDEX_LEAF *pSearchIndexLeaf = m_pRoot;
//搜索中當(dāng)前的數(shù)據(jù)葉
BTREE_DATA_LEAF *pSearchDataLeaf = NULL;
if ( !pSearchIndexLeaf ) //B+Tree 的最原始狀態(tài),連根都沒(méi)有
{
//生成根
pSearchIndexLeaf = NewIndexLeaf();
if ( !pSearchIndexLeaf ) return -2;
pSearchDataLeaf = NewDataLeaf();
if ( !pSearchDataLeaf ) return -2;
pSearchIndexLeaf->IndexKeys[0].pKeyRight = pSearchDataLeaf;
RECTYPE *pTmp = NewRecType();
if( !pTmp ) return -2;
DATA_CONTAINER *pDataCont = NewDataContainer();
if( !pDataCont ) return -2;
pDataCont->pData = pTmp;
*pTmp = Key;
pSearchIndexLeaf->cPointerType = DATA_LEAF_POINTER;
pSearchIndexLeaf->IndexKeys[0].pKey = pTmp;
pSearchDataLeaf->pDataCont[0] = pDataCont;
m_pRoot = pSearchIndexLeaf;
return 0;
}
//查找可以容納 Key 的數(shù)據(jù)葉
bool bKeyInIndex = false;
int i = GetDataLeaf( Key, pSearchIndexLeaf, pSearchDataLeaf, &bKeyInIndex );
if ( i < 0 )
return -1; //B+Tree 錯(cuò)誤
if( !pSearchDataLeaf )
{
//來(lái)到這里的唯一可能性就是
//索引葉的最左指針為 NULL
//而且這棵樹(shù)只有一個(gè)索引葉和一個(gè)數(shù)據(jù)葉
pSearchDataLeaf = NewDataLeaf(); //就給它一個(gè)新的
if( !pSearchDataLeaf ) return -2;
pSearchIndexLeaf->pLeafLeft = pSearchDataLeaf;
}
//在數(shù)據(jù)葉中查找 Key 是否存在
DATA_CONTAINER *pDataCont ;
if( bKeyInIndex )
else
pDataCont = SeekInDataLeaf( pSearchDataLeaf, Key, NULL);
if( pDataCont )
{
//存在!
//建立 Key 鏈表
while ( pDataCont->pNext )
pDataCont = (DATA_CONTAINER *)pDataCont->pNext;
DATA_CONTAINER *pDataCont2 = NewDataContainer();
if( !pDataCont2) return -2; //沒(méi)有內(nèi)存
pDataCont->pNext = pDataCont2;
pDataCont2->pProv = pDataCont;
pDataCont2->pData = NewRecType();
if( !pDataCont2->pData ) return -2;
*(pDataCont2->pData) = Key;
//return 0;
return 1; //表示該Key已經(jīng)存在
}
//InsertAgain:
//如果數(shù)據(jù)葉有空位置
int nDataLeafLoc = GetFreeElemInDataLeaf( pSearchDataLeaf );
if ( nDataLeafLoc > -1 )
{
//數(shù)據(jù)葉有空位置
DATA_CONTAINER *pTmp = NewDataContainer();
if( !pTmp ) return -2;
pTmp->pData = NewRecType();
if( !pTmp->pData ) return -2;
*(pTmp->pData) = Key;
QuickSortData( pSearchDataLeaf->pDataCont, 0, nDataLeafLoc, pTmp );
}
else
{
//如果數(shù)據(jù)葉已經(jīng)滿(mǎn)了,看看他的兄弟有沒(méi)有空間
if ( i > 0 ) //看看左邊的數(shù)據(jù)葉
{
BTREE_DATA_LEAF *pDataLeaf;
if ( i == 1)
{
pDataLeaf = (BTREE_DATA_LEAF *)pSearchIndexLeaf->pLeafLeft;
if ( !pDataLeaf)
{
pDataLeaf = NewDataLeaf();
if( !pDataLeaf ) return -2;
pSearchIndexLeaf->pLeafLeft = pDataLeaf;
}
}
else pDataLeaf = (BTREE_DATA_LEAF *)pSearchIndexLeaf->IndexKeys[i-2].pKeyRight;
if ( ! pDataLeaf )
return -1;
int nDataLeafLoc = GetFreeElemInDataLeaf( pDataLeaf );
//左邊的兄弟有空
if ( nDataLeafLoc >= 0 )
{
//開(kāi)始把數(shù)據(jù)從右往左旋轉(zhuǎn)
pDataLeaf->pDataCont[nDataLeafLoc] = pSearchDataLeaf->pDataCont[0];
DATA_CONTAINER *pTmp = NewDataContainer();
if( !pTmp) return -2;
pTmp->pData = NewRecType();
if( !pTmp->pData ) return -2;
*(pTmp->pData) = Key;
QuickSortData( pSearchDataLeaf->pDataCont, 1, BTREE_DEGREE, pTmp);
pSearchIndexLeaf->IndexKeys[i-1].pKey = pSearchDataLeaf->pDataCont[0]->pData;
return 0;
}
}
if ( i < BTREE_DEGREE ) //看看右邊的數(shù)據(jù)葉
{
BTREE_DATA_LEAF *pDataLeaf;
if ( pSearchIndexLeaf->IndexKeys[i].pKey )
{
pDataLeaf = (BTREE_DATA_LEAF *)pSearchIndexLeaf->IndexKeys[i].pKeyRight;
if ( ! pDataLeaf )
return -1;
int nDataLeafLoc = GetFreeElemInDataLeaf( pDataLeaf );
//右邊的兄弟有空
if ( nDataLeafLoc > -1 )
{
//開(kāi)始把數(shù)據(jù)從左往右旋轉(zhuǎn)
int j;
//pDataLeaf->pDataCont[nDataLeafLoc] = pSearchDataLeaf->pDataCont[0];
//先騰出空間
for ( j = nDataLeafLoc; j > 0; j--)
pDataLeaf->pDataCont[j] = pDataLeaf->pDataCont[j-1];
//到底應(yīng)不應(yīng)該把 Key 移動(dòng)
//就得看看數(shù)據(jù)葉的最后一個(gè)元素的大小
if ( *(pSearchDataLeaf->pDataCont[BTREE_DEGREE-1]->pData) < Key )
{
pDataLeaf->pDataCont[0] = NewDataContainer();
if( !pDataLeaf->pDataCont[0]) return -2;
pDataLeaf->pDataCont[0]->pData = NewRecType();
if( !pDataLeaf->pDataCont[0]->pData ) return -2;
*(pDataLeaf->pDataCont[0]->pData) = Key;
pSearchIndexLeaf->IndexKeys[i].pKey = pDataLeaf->pDataCont[0]->pData;
}
else
{
pDataLeaf->pDataCont[0] = pSearchDataLeaf->pDataCont[BTREE_DEGREE-1];
DATA_CONTAINER *pTmp = NewDataContainer();
if( !pTmp ) return -2;
pTmp->pData = NewRecType();
if( !pTmp->pData) return -2;
*(pTmp->pData) = Key;
QuickSortData( pSearchDataLeaf->pDataCont,0, BTREE_DEGREE-1,pTmp );
pSearchIndexLeaf->IndexKeys[i].pKey = pDataLeaf->pDataCont[0]->pData;
}
return 0;
}
}
}
m_bMadeList = false;
//左右兄弟都沒(méi)有空間
//只好把數(shù)據(jù)葉拆分成兩個(gè)
BTREE_DATA_LEAF *pDataLeaf = NewDataLeaf();
if( !pDataLeaf ) return -2;
INDEX_KEY NewKey;
int j,k,l;
for ( j = (BTREE_DEGREE / 2), k = 0; j < BTREE_DEGREE; j++, k++)
{
pDataLeaf->pDataCont[k] = pSearchDataLeaf->pDataCont[j];
pSearchDataLeaf->pDataCont[j] = NULL;
}
//數(shù)據(jù)葉拆分后,新增的 Key 應(yīng)該放在那一方.
if ( Key < *(pDataLeaf->pDataCont[0]->pData) )
{
DATA_CONTAINER *pTmp = NewDataContainer();
if( !pTmp ) return -2;
pTmp->pData = NewRecType();
if( !pTmp->pData ) return -2;
*(pTmp->pData) = Key;
QuickSortData( pSearchDataLeaf->pDataCont, 0, BTREE_DEGREE / 2, pTmp);
}
else
{
DATA_CONTAINER *pTmp = NewDataContainer();
if( !pTmp ) return -2;
pTmp->pData = NewRecType();
if( !pTmp->pData ) return -2;
*(pTmp->pData) = Key;
QuickSortData( pDataLeaf->pDataCont, 0, k, pTmp);
}
//要插入到索引葉的 NewKey
NewKey.pKey = pDataLeaf->pDataCont[0]->pData;
NewKey.pKeyRight = pDataLeaf;
//數(shù)據(jù)葉沒(méi)有空位,看看索引葉有沒(méi)有
int nIndexLeafLoc = GetFreeElemInIndexLeaf( pSearchIndexLeaf );
if ( nIndexLeafLoc > -1 )
{
//索引葉有空位
for ( l = nIndexLeafLoc; l > i ; l -- )
{
pSearchIndexLeaf->IndexKeys[l] = pSearchIndexLeaf->IndexKeys[l-1];
}
pSearchIndexLeaf->IndexKeys[i] = NewKey;
}
else
//數(shù)據(jù)葉和索引葉都沒(méi)有空位置
{
if ( SplitIndexLeaf(pSearchIndexLeaf,
NewKey, i ) < 0 )
return -1;
}
}
return 0;
}
//向B+Tree 中查找 Key
//返回 NULL,表示查找不到,否則返回符合條件的 RECTYPE*
// pLessThan 如果不為NULL,返回時(shí)存放的就是比 Key 小的 RECTYPE*
// pGreaterThan 如果不為NULL,返回時(shí)存放的就是比 Key 大的 RECTYPE*
template <class RECTYPE>
RECTYPE* CMXBTree<RECTYPE>::SearchKey( RECTYPE & Key, SEARCH_KEY *pSK, RECTYPE **pLessThan, RECTYPE **pGreaterThan )
{
if( pSK )
memset( pSK, 0, sizeof(SEARCH_KEY) );
if( ( pSK || pLessThan || pGreaterThan) && MakeDataList() < 0 ) //先做列表
{
if( pLessThan ) *pLessThan = NULL;
if( pGreaterThan ) *pGreaterThan = NULL;
return NULL;
}
//搜索中當(dāng)前的索引葉
BTREE_INDEX_LEAF *pSearchIndexLeaf = m_pRoot;
//搜索中當(dāng)前的數(shù)據(jù)葉
BTREE_DATA_LEAF *pSearchDataLeaf = NULL;
BTREE_DATA_LEAF *pSearchDataLeaf2;
DATA_CONTAINER *pSearchResult;
RECTYPE* pRet;
bool KeyInIndex = false;
if ( (GetDataLeaf( Key, pSearchIndexLeaf, pSearchDataLeaf, &KeyInIndex )) < 0 ) return NULL;
if ( pSearchDataLeaf == NULL )
{
//唯一的可能性是 pSearchIndexLeaf 的 pLeftLeaf 為 NULL
if( pLessThan ) *pLessThan = NULL;
if( pGreaterThan ) *pGreaterThan = pSearchIndexLeaf->IndexKeys[0].pKey;
return NULL;
}
int i;
if ( KeyInIndex )
{
//索引葉中已經(jīng)有了Key了
pSearchResult = pSearchDataLeaf->pDataCont[0];
i = 0;
}
else
pSearchResult = SeekInDataLeaf( pSearchDataLeaf,Key, &i);
if( pSK )
{
pSK->m_pSearchResultOrig = pSearchResult;
pSK->m_pSearchDataLeaf = pSearchDataLeaf;
pSK->m_GetKey.m_nDataElemIndex = i;
pSK->m_GetKey.m_pProv = pSearchDataLeaf;
pSK->m_GetKey.m_DataCont = pSearchResult;
}
if( pSearchResult == NULL ) //在數(shù)據(jù)葉中沒(méi)有該 Key
{
if( i == 0)
{
if( pLessThan )
{
if( pSearchDataLeaf->pProv )
{
pSearchDataLeaf2 = pSearchDataLeaf->pProv;
int j = GetTotalElemInDataLeaf( pSearchDataLeaf->pProv );
*pLessThan = pSearchDataLeaf2->pDataCont[j-1]->pData;
}
else *pLessThan = NULL;
}
if( pGreaterThan )
*pGreaterThan = pSearchDataLeaf->pDataCont[0]->pData;
}
else
{
if( pLessThan )
*pLessThan = pSearchDataLeaf->pDataCont[i-1]->pData;
if( pGreaterThan )
{
if( i < BTREE_DEGREE && pSearchDataLeaf->pDataCont[i] )
*pGreaterThan = pSearchDataLeaf->pDataCont[i]->pData;
else
{
if( pSearchDataLeaf->pNext )
{
pSearchDataLeaf2 = pSearchDataLeaf->pNext;
*pGreaterThan = pSearchDataLeaf2->pDataCont[0]->pData;
}
else *pGreaterThan = NULL;
}
}
}
return NULL;
}
else
{
if( i == 0)
{
if( pLessThan )
{
if( pSearchDataLeaf->pProv )
{
pSearchDataLeaf2 = pSearchDataLeaf->pProv;
int j = GetTotalElemInDataLeaf( pSearchDataLeaf->pProv );
*pLessThan = pSearchDataLeaf2->pDataCont[j-1]->pData;
}
else *pLessThan = NULL;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -