亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? cmxbtree.cpp

?? CMXBTree 的主要作用是在內存中建立一棵B+樹
?? CPP
?? 第 1 頁 / 共 4 頁
字號:
#ifndef _CMXBTREE_CPP_20010925
#define _CMXBTREE_CPP_20010925

//以下內容是 CMXBTree 的實現
//所有代碼由 鄔穩 編寫于 2001.9
//版權所有:深圳科邁通訊技術有限公司 2001.9


#include "cmxbtree.h"

//排序
//參數 A 已經是排好序的隊列
//Key 指向要插入的元素
//0     1      2      3      4
//|-----|--30--|--75--|--85--|
//   ^  nLo                 nHi
//   |
// 可用空間
//假設 Key == 15
template <class RECTYPE>
void CMXBTree<RECTYPE>::QuickSortData(DATA_CONTAINER **A, int nLo, int nHi, DATA_CONTAINER *Key)
{
    int i;
    int iHi = nHi;
    int iLo = nLo;
    bool bLoop = true;

    if( iHi == 0) //如果隊列 A 中一個元素都沒有
    {
        A[0] = Key;
        return;
    }

    if( iHi - iLo == 1) //如果隊列 A 中只有一個元素
    {
        bLoop = false; //不用進入下面的 while 循環
        if( *(Key->pData) < *(A[iLo]->pData) )
            i = iLo;
        else i = iHi;
    }

    while( bLoop ) //隊列 A 有兩個或以上的元素時、才能進入 while 循環
    {
        //以下用二分法尋找可以插入的位置
        //這個位置就放在 i 中

        i = (iLo+iHi)/2;
        if( (i == iLo) && ( i== iHi ) )  break;
        if( *(Key->pData) < *(A[i-1]->pData)   )
        {
            iHi = i - 1;
            continue;
        }
        else
        if( *(Key->pData) < *(A[i]->pData)  )
        {
            break;
        }
        else iLo = i + 1;
    }
    
    int l;
    
    if( i == nLo && i > 0) //在最左邊插入,而且左邊有空
    {
        A[i-1] = Key;
        return ;
    }

    if( i == nHi && i < BTREE_DEGREE ) //在最右邊插入,而且右邊有空
    {
        A[i] = Key;
        return;
    }

    //需要在中間的某個地方插入
    if( nLo > 0 ) //左邊有空,往左邊推
    {
        for( l = 0; l < i-1 ; l ++)
            A[l] = A[l+1];
        A[i-1] = Key;
    }
    else //右邊有空,往左邊推
    {
        for( l = nHi-1; l >=i ; l --)
            A[l+1] = A[l];
        A[i] = Key;
    }
}

//申請一個新的索引葉
//如果不夠內存,返回 NULL 
template <class RECTYPE>
CMXBTree<RECTYPE>::BTREE_INDEX_LEAF *CMXBTree<RECTYPE>::NewIndexLeaf( void )
{
    BTREE_INDEX_LEAF *pTmp = new BTREE_INDEX_LEAF;
    if ( !pTmp ) return NULL;
    
    m_nNewIndexLeaf ++;

    memset( pTmp, 0, sizeof( BTREE_INDEX_LEAF ) );
    return pTmp;
}

template <class RECTYPE>
void CMXBTree<RECTYPE>::DeleteIndexLeaf( BTREE_INDEX_LEAF * pPtr )
{
    m_nDelIndexLeaf ++;
    if( pPtr ) delete pPtr;
}

//申請一個新的數據葉
//如果不夠內存,返回 NULL 
template <class RECTYPE>
CMXBTree<RECTYPE>::BTREE_DATA_LEAF *CMXBTree<RECTYPE>::NewDataLeaf( void )
{
    BTREE_DATA_LEAF *pTmp = new BTREE_DATA_LEAF;
    if ( !pTmp ) return NULL;

    m_nNewDataLeaf ++;

    memset( pTmp, 0, sizeof( BTREE_DATA_LEAF ) );
    return pTmp;
}

template <class RECTYPE>
void CMXBTree<RECTYPE>::DeleteDataLeaf( BTREE_DATA_LEAF * pPtr )
{
    m_nDelDataLeaf ++;
    if( pPtr ) delete pPtr;
}

//申請一個新的 DataContainer
//如果不夠內存,返回 NULL 
template <class RECTYPE>
CMXBTree<RECTYPE>::DATA_CONTAINER *CMXBTree<RECTYPE>::NewDataContainer( void )
{
    DATA_CONTAINER *pTmp = new DATA_CONTAINER;
    if ( !pTmp ) return NULL;
    
    m_nNewDataCon ++;

    memset( pTmp, 0, sizeof( DATA_CONTAINER ) );
    return pTmp;
}

template <class RECTYPE>
void CMXBTree<RECTYPE>::DeleteDataContainer( DATA_CONTAINER *pPtr )
{

    m_nDelDataCon ++;
    if( pPtr ) delete pPtr;
}

//申請一個新的 RECTYPE
//如果不夠內存,返回 NULL
template <class RECTYPE>
RECTYPE *CMXBTree<RECTYPE>::NewRecType( void )
{
    RECTYPE *pTmp = new RECTYPE;
    if ( !pTmp ) return NULL;

    m_nNewRecType ++;
    
    //memset( pTmp, 0, sizeof( RECTYPE ) );
    return pTmp;
}

template <class RECTYPE>
void CMXBTree<RECTYPE>::DeleteRecType( RECTYPE *pPtr )
{

    m_nDelRecType ++;
    if( pPtr ) delete pPtr;
}

//數據葉是否還有空位
//如果有空位則返回空位的位置 0 ~ BTREE_DEGREE - 1
//否則 返回 -1
template <class RECTYPE>
int CMXBTree<RECTYPE>::GetFreeElemInDataLeaf( BTREE_DATA_LEAF *pDataLeaf )
{
    for ( int i = 0 ; i < BTREE_DEGREE ; i++ )
    {
        if ( ! pDataLeaf->pDataCont[i] ) return i;
    }
    return -1;
}

//數據葉存放了多少元素
//返回值 0 ~ BTREE_DEGREE
template <class RECTYPE>
int CMXBTree<RECTYPE>::GetTotalElemInDataLeaf( BTREE_DATA_LEAF *pDataLeaf )
{
    for ( int i = 0 ; i < BTREE_DEGREE ; i++ )
    {
        if ( ! pDataLeaf->pDataCont[i] ) return i;
    }
    return BTREE_DEGREE;
}

//索引葉是否還有空位
//如果有空位則返回空位的位置 0 ~ BTREE_DEGREE - 1
//否則 返回 -1
template <class RECTYPE>
int CMXBTree<RECTYPE>::GetFreeElemInIndexLeaf( BTREE_INDEX_LEAF *pIndexLeaf )
{
    for ( int i = 0 ; i < BTREE_DEGREE ; i++ )
    {
        if ( ! (pIndexLeaf->IndexKeys[i].pKey) ) return i;
    }
    return -1;
}

//索引葉存放了多少元素
//返回值 0 ~ BTREE_DEGREE
template <class RECTYPE>
int CMXBTree<RECTYPE>::GetTotalElemInIndexLeaf( BTREE_INDEX_LEAF *pIndexLeaf )
{
    for ( int i = 0 ; i < BTREE_DEGREE ; i++ )
    {
        if ( ! (pIndexLeaf->IndexKeys[i].pKey) ) return i;
    }
    return BTREE_DEGREE;
}

//在索引葉中尋找可以插入Key的縫隙
//返回 0 ~ DEGREE 表示縫隙的位置
//返回 -1 表示B+Tree Error
template <class RECTYPE>
int CMXBTree<RECTYPE>::SeekInsertPoint( BTREE_INDEX_LEAF * pSearchIndexLeaf, RECTYPE & Key, bool *pKeyInIndex)
{
    if( pSearchIndexLeaf == NULL ) return -1;

    int i;
    int nLo = 0 , nHi = BTREE_DEGREE;
    
    while( true )
    {
        i = (nLo + nHi )/2;
        if( i == nLo && i == nHi ) return i; //發現了
        if( i == 0) //到了最左邊
        {
            if( ! pSearchIndexLeaf->IndexKeys[0].pKey ) return -1;
            if( Key < *(pSearchIndexLeaf->IndexKeys[0].pKey) )
                return i;
            else 
            {
                nLo = i + 1;
                continue;
            }
        }
        //如果左邊的元素空或者小于 Key
        if( !pSearchIndexLeaf->IndexKeys[i-1].pKey || Key < *(pSearchIndexLeaf->IndexKeys[i-1].pKey) )
        {
            nHi = i - 1;
            continue;
        }
        else
        if( pSearchIndexLeaf->IndexKeys[i].pKey ) //右邊有元素
        {
            if( *(pSearchIndexLeaf->IndexKeys[i].pKey) < Key ) //比右邊的元素大一點
            {
                nLo = i +1;
                continue;
            }
            else
            if( Key < *(pSearchIndexLeaf->IndexKeys[i].pKey) ) //比右邊的元素小一點
                return i;
            else 
            {
                if( pKeyInIndex )
                    *pKeyInIndex = true;
                return i + 1;
            }
        }
        else //右邊沒有元素存在
            return i;
    }
    //return -1;
}

//取得可以存放 Key 的數據葉
//返回數據葉的索引葉的縫隙
//返回 -1 表示B+Tree 出錯
template <class RECTYPE>
int CMXBTree<RECTYPE>::GetDataLeaf( RECTYPE &Key, BTREE_INDEX_LEAF * &pSearchIndexLeaf, BTREE_DATA_LEAF  * &pSearchDataLeaf, bool *pKeyInIndex )
{
    int i;
  
    //int nLo = 0 , nHi = BTREE_DEGREE;  
    while( true ) //一直循環
    {
        if( !pSearchIndexLeaf ) 
            return -1;
        if( pKeyInIndex && *pKeyInIndex )
            i = 0;
        else
            i = SeekInsertPoint( pSearchIndexLeaf, Key, pKeyInIndex); //查詢插入位置
        if( i < 0 ) 
            return -1;
        void *pTmp;
        if( i == 0 )
            pTmp = pSearchIndexLeaf->pLeafLeft;
        else pTmp = pSearchIndexLeaf->IndexKeys[i-1].pKeyRight;

        if( pSearchIndexLeaf->cPointerType == DATA_LEAF_POINTER) //如果下面就是數據葉
        {
            pSearchDataLeaf = (BTREE_DATA_LEAF*)pTmp;
            return i;
        }
        else
        if( pSearchIndexLeaf->cPointerType == INDEX_LEAF_POINTER) //如果下面是索引葉
        {
            if( !pTmp ) 
                return -1;
            BTREE_INDEX_LEAF* pTmp2 = pSearchIndexLeaf;
            pSearchIndexLeaf = (BTREE_INDEX_LEAF*)pTmp;  //繼續找下一個
            pSearchIndexLeaf->pParent = pTmp2;
            continue;            
        }
    }
}

//查找索引葉在父節點的位置
template <class RECTYPE>
int CMXBTree<RECTYPE>::SeekParent( BTREE_INDEX_LEAF * pParentLeaf, BTREE_INDEX_LEAF * pIndexLeaf)
{
    if ( pIndexLeaf == pParentLeaf->pLeafLeft ) return 0;
    else
    {
        int l;
        for( l = 0; l < BTREE_DEGREE; l ++ )
        {
            if( pIndexLeaf == pParentLeaf->IndexKeys[l].pKeyRight )
                return l + 1;
        }
        //尋找不到,BTREE 錯誤
        if ( l == BTREE_DEGREE ) 
            return -1;
    }
    return -1;
}

//分裂索引葉
//這個函數被 InsertKey 調用,
//調用背景是在數據葉的索引葉滿了之后,
//需要對索引葉進行分裂
template <class RECTYPE>
int CMXBTree<RECTYPE>::SplitIndexLeaf(BTREE_INDEX_LEAF * pCurIndexLeaf, //要容納新 Key 的索引葉
                    INDEX_KEY NewKey,       //新的 Key
                    int i )                 //插入位置 0 ~ BTREE_DEGREE
{
    INDEX_KEY TmpIndexKeys[BTREE_DEGREE + 1]; //能容納所有 Key 的臨時變量
    int j;    
    int l;

SplitAgain:

    memcpy(TmpIndexKeys, pCurIndexLeaf->IndexKeys, BTREE_DEGREE * sizeof( INDEX_KEY ));

    for( l = BTREE_DEGREE; l > i; l-- )
    {
        TmpIndexKeys[l] = TmpIndexKeys[l-1];
    }
    TmpIndexKeys[i] = NewKey;

    //如果自己就是根
    if ( !pCurIndexLeaf->pParent )
    {

        //新增兩個索引葉
        BTREE_INDEX_LEAF *pIndexLeaf1 = NewIndexLeaf();
        if( !pIndexLeaf1 ) return -2;

        BTREE_INDEX_LEAF *pIndexLeaf2 = NewIndexLeaf();
        if( !pIndexLeaf2 ) return -2;

        int nCutPosition = (BTREE_DEGREE + 1)/2;
        
        //給這兩個索引葉賦值
        for(l = 0 ; l < nCutPosition; l ++)
        {
            pIndexLeaf1->IndexKeys[l] = TmpIndexKeys[l] ;
        }

        pIndexLeaf1->pLeafLeft = pCurIndexLeaf->pLeafLeft;
        pIndexLeaf1->cPointerType = pCurIndexLeaf->cPointerType;
        pIndexLeaf1->pParent = pCurIndexLeaf;

        for(l = nCutPosition + 1,j = 0 ; l < BTREE_DEGREE+1; l ++, j++)
        {
            pIndexLeaf2->IndexKeys[j] = TmpIndexKeys[l] ;
        }
        pIndexLeaf2->pLeafLeft = TmpIndexKeys[nCutPosition].pKeyRight;
        pIndexLeaf2->cPointerType = pCurIndexLeaf->cPointerType;
        pIndexLeaf2->pParent = pCurIndexLeaf;
        
        //清空根的索引葉
        memset(pCurIndexLeaf->IndexKeys, 0, BTREE_DEGREE * sizeof( INDEX_KEY ));
        pCurIndexLeaf->IndexKeys[0].pKey = TmpIndexKeys[nCutPosition].pKey;
        pCurIndexLeaf->IndexKeys[0].pKeyRight = pIndexLeaf2;
        pCurIndexLeaf->pLeafLeft = pIndexLeaf1;

        //最后才設置 POINTER TYPE
        pCurIndexLeaf->cPointerType = INDEX_LEAF_POINTER;    
        return 0;
    }
    else
    //父節點存在
    {
        int nIndexLoc;

        //尋找 pCurIndexLeaf 在父節點的位置
        BTREE_INDEX_LEAF *pParentIndex = pCurIndexLeaf->pParent;
        nIndexLoc = SeekParent( pParentIndex, pCurIndexLeaf);
        if( nIndexLoc < 0 ) 
            return -1;

        if ( nIndexLoc < BTREE_DEGREE ) //往右看有沒有兄弟有空
        {
            
            BTREE_INDEX_LEAF *pIndexLeaf;
            //右邊有沒有兄弟存在
            if ( pParentIndex->IndexKeys[nIndexLoc].pKey )
            {
                //將右邊的兄弟取下來
                pIndexLeaf = (BTREE_INDEX_LEAF *)pParentIndex->IndexKeys[nIndexLoc].pKeyRight;
                if ( ! pIndexLeaf ) 
                    return -1;
                int nIndexLeafLoc = GetFreeElemInIndexLeaf( pIndexLeaf );
                //右邊的兄弟有空
                if ( nIndexLeafLoc > -1 )
                {
                    //擠出空間出來
                    for ( j = nIndexLeafLoc; j > 0; j--)
                    {
                        pIndexLeaf->IndexKeys[j] = pIndexLeaf->IndexKeys[j-1];
                    }
                    pIndexLeaf->IndexKeys[0].pKey = pParentIndex->IndexKeys[nIndexLoc].pKey;
                    pIndexLeaf->IndexKeys[0].pKeyRight = pIndexLeaf->pLeafLeft;
                    pIndexLeaf->pLeafLeft = TmpIndexKeys[BTREE_DEGREE].pKeyRight;
                    pParentIndex->IndexKeys[nIndexLoc].pKey = TmpIndexKeys[BTREE_DEGREE].pKey ;
                    pParentIndex->IndexKeys[nIndexLoc].pKeyRight = pIndexLeaf;
                    memcpy(pCurIndexLeaf->IndexKeys, TmpIndexKeys, BTREE_DEGREE * sizeof( INDEX_KEY ));

                    return 0;
                }
            }
        }
        if ( nIndexLoc > 0 ) //看看左邊的索引葉
        {
            BTREE_INDEX_LEAF *pParentIndex = pCurIndexLeaf->pParent;
            BTREE_INDEX_LEAF *pIndexLeaf;
            if ( nIndexLoc == 1)
            {

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩三级一区| 91精品国产乱码久久蜜臀| 老司机精品视频在线| 日本美女一区二区| 美女免费视频一区二区| 日韩国产在线一| 六月丁香综合在线视频| 蜜桃精品在线观看| 国产剧情一区在线| 国产成人精品免费网站| 成人黄色在线网站| 91国偷自产一区二区三区观看| 色综合久久99| 在线成人免费视频| 欧美成人精品3d动漫h| 26uuu亚洲综合色欧美 | 一区二区三区av电影 | 制服丝袜亚洲色图| 日韩欧美一二三区| 国产日产欧产精品推荐色| 国产精品久久夜| 图片区小说区区亚洲影院| 国精产品一区一区三区mba桃花| 黄页网站大全一区二区| av网站一区二区三区| 在线免费观看日本欧美| 欧美肥妇毛茸茸| 久久久久久久久久看片| 一区二区三区中文免费| 久久er99热精品一区二区| 成人免费av资源| 欧美日韩一区二区电影| 国产欧美精品在线观看| 亚洲尤物视频在线| 国内精品免费在线观看| 99这里只有久久精品视频| 欧美蜜桃一区二区三区| 日本一区二区动态图| 丝袜亚洲另类欧美| 91在线国产福利| 2020日本不卡一区二区视频| 亚洲影视资源网| 国产福利一区二区三区在线视频| 欧美性一级生活| 久久精品视频网| 青青草成人在线观看| 91视视频在线直接观看在线看网页在线看 | 精品一区二区三区的国产在线播放 | 精品国产免费视频| 亚洲与欧洲av电影| 99国产精品国产精品毛片| 欧美一级黄色录像| 五月激情综合网| 在线区一区二视频| 亚洲人成网站影音先锋播放| 国内精品写真在线观看| 91麻豆精品国产91久久久久久久久| 亚洲欧美日韩中文播放| 成人avav影音| 久久久国产综合精品女国产盗摄| 蜜臀a∨国产成人精品| 欧美日韩在线一区二区| 伊人夜夜躁av伊人久久| 99这里都是精品| 国产精品美女久久久久久2018| 国产精品亚洲视频| 久久久精品人体av艺术| 国产专区欧美精品| 久久婷婷成人综合色| 精久久久久久久久久久| 日韩一级完整毛片| 奇米色一区二区| 91精品国产综合久久久久久| 亚洲综合色成人| 欧美日韩一二区| 日韩黄色片在线观看| 欧美疯狂性受xxxxx喷水图片| 午夜精品福利在线| 欧美男男青年gay1069videost | 中文字幕二三区不卡| 亚洲影视在线播放| 久久国产婷婷国产香蕉| 久久综合色播五月| 91激情五月电影| 成人免费毛片aaaaa**| 久久福利资源站| 午夜欧美在线一二页| 国产精品久久777777| 久久一区二区三区国产精品| 欧美精品乱码久久久久久按摩 | 欧美大度的电影原声| 在线精品观看国产| av中文字幕在线不卡| 国内一区二区视频| 裸体歌舞表演一区二区| 亚洲成人手机在线| 一区二区三区免费网站| 国产精品美女久久久久av爽李琼| 精品国产露脸精彩对白| 欧美麻豆精品久久久久久| 欧美在线影院一区二区| 在线免费亚洲电影| 99久久99久久精品国产片果冻| 国产成人在线免费| 国产激情一区二区三区| 国产在线一区二区| 国产乱码字幕精品高清av| 秋霞av亚洲一区二区三| 日韩国产欧美在线观看| 五月天一区二区| 日本亚洲免费观看| 麻豆免费看一区二区三区| 男男成人高潮片免费网站| 日韩国产高清影视| 美女视频免费一区| 久久99精品国产麻豆婷婷| 狠狠色丁香久久婷婷综| 久久超碰97中文字幕| 国产一区不卡视频| 国产成人精品三级麻豆| 波多野结衣视频一区| eeuss影院一区二区三区| 99r精品视频| 91搞黄在线观看| 欧美喷潮久久久xxxxx| 欧美一区二区三区日韩| 欧美不卡一区二区三区| 国产日韩成人精品| 亚洲三级久久久| 亚洲bt欧美bt精品777| 日本亚洲三级在线| 国产成人99久久亚洲综合精品| 懂色av一区二区三区蜜臀| 91蜜桃免费观看视频| 欧美日韩黄色影视| 欧美tk—视频vk| 国产精品丝袜久久久久久app| 亚洲另类色综合网站| 日本麻豆一区二区三区视频| 国内外成人在线| 北岛玲一区二区三区四区| 欧美日韩在线观看一区二区| 精品少妇一区二区三区在线视频| 欧美激情一二三区| 亚洲综合在线观看视频| 麻豆国产91在线播放| aaa亚洲精品| 6080日韩午夜伦伦午夜伦| 久久久久久久久久美女| 亚洲黄色免费电影| 韩国女主播成人在线| av电影天堂一区二区在线| 91.com在线观看| 国产精品三级久久久久三级| 亚洲一区精品在线| 国内成人精品2018免费看| 在线观看日韩av先锋影音电影院| 日韩午夜激情视频| 亚洲男女毛片无遮挡| 久久se这里有精品| 欧美午夜片在线看| 中文字幕的久久| 裸体歌舞表演一区二区| 色婷婷久久一区二区三区麻豆| 精品国产网站在线观看| 亚洲国产视频一区二区| 国产**成人网毛片九色| 91精品婷婷国产综合久久性色| 国产精品久久精品日日| 国产尤物一区二区在线| 欧美日韩视频在线一区二区| 中文字幕一区二区三区四区不卡 | 亚洲一区二区在线免费观看视频| 狠狠狠色丁香婷婷综合激情| 欧美精品xxxxbbbb| 亚洲精品乱码久久久久| 成人av资源在线| 精品国产在天天线2019| 婷婷综合另类小说色区| 91精彩视频在线观看| 亚洲国产精品二十页| 蜜桃视频第一区免费观看| 欧美人伦禁忌dvd放荡欲情| 亚洲欧洲综合另类| 成年人网站91| 国产日韩精品久久久| 狠狠色狠狠色综合系列| 欧美zozo另类异族| 美女视频一区在线观看| 欧美一区二区国产| 男女男精品视频| 欧美一区二区三区免费视频| 亚洲成a人v欧美综合天堂 | 亚洲午夜三级在线| 在线免费观看日本欧美| 一区二区久久久| 色婷婷亚洲综合| 自拍视频在线观看一区二区| 不卡的电视剧免费网站有什么| 中国av一区二区三区|