学习笔记:B+树模拟数据库索引查找

来源:互联网 发布:软件质量分析报告 编辑:程序博客网 时间:2024/06/05 21:53
#include <iostream>#include <queue>using namespace std;/******************************PROGRAMER: FanchenxinM 阶B+树:            (1) 非叶子节点key 个数和子树指针最大个数均为M.            (2) 非叶子节点的key 为其子树节点M个key的最大或最小key.?            (3) 叶子节点保存所有的key .B+的特性:            1.所有关键字都出现在叶子结点的链表中(稠密索引),                且链表中的关键字恰好是有序的            2.不可能在非叶子结点命中;                   3.非叶子结点相当于是叶子结点的索引(稀疏索引),                叶子结点相当于是存储(关键字)数据的数据层;                   4.更适合文件索引系统******************************//* 表结构 */typedef struct _TableStruct_{    char name[20];  // 名字作为索引的关键字,经过某种运算成为一个整数关键字,假设名字没有重名的情况    int age;    char addr[256];}TABLE_ST;static TABLE_ST peopleInfoTable[20] = {    {"杨洋", 20, "河北省秦皇岛市"},    {"张占音", 21, "河南省许昌市"},    {"沈东镇", 23, "黑龙江省讷河"},    {"孟苏", 15, "河北省石家庄"},    {"杨大勇", 20, "河北省唐山市"},    {"李桂珍", 12, "上海市"},    {"钱伟", 23, "福建省宁德"},    {"蔡景观", 14, "陕西省宝鸡"},    {"孙大宝", 35, "内蒙古包头"},    {"赵国", 23, "四川省"},    {"杨过", 21, "辽宁省大连市"},    {"张勇", 21, "河南省许昌市"},    {"沈陈东", 27, "江西省许昌市"},    {"孟大海", 56, "海南"},    {"杨治国", 34, "山东省"},    {"李正", 14, "北京市"},    {"钱爱装", 23, "山西省"},    {"蔡大头", 14, "厦门市"},    {"孙树", 35, "辽宁省沈阳市"},    {"赵本山", 60, "辽宁省铁岭市"},};  //人口信息表#define M (4)typedef struct _BPlusTreeNode_{    int keyNum;    int key[M];    bool isLeaf;    struct _BPlusTreeNode_* subTree[M];    struct _BPlusTreeNode_* father;    //struct _BPlusTreeNode_* nextLeaf;  // 只有是叶子节点的时候才用到    void* dataAddr[M];  //叶子节点指向的数据地址}BPlusTreeNode;BPlusTreeNode* newBPlusTreeNode(bool is_Leaf){    BPlusTreeNode* newNode = (BPlusTreeNode*)malloc(sizeof(BPlusTreeNode));    if(newNode != NULL)    {        newNode->keyNum = 0;        memset(newNode->key, 0, (M) * sizeof(int));        newNode->isLeaf = is_Leaf;        memset(newNode->subTree, NULL, M * sizeof(BPlusTreeNode*));        newNode->father = NULL;        memset(newNode->dataAddr, NULL, M * sizeof(void*));    }    else        return NULL;    return newNode;}/* father为需要分裂的节点的父节点    splitChildIdx 为需要分裂的节点的index, */void splitChild(BPlusTreeNode* father, int splitChildIdx, int key){    if(!father)        return;    /*father->subTree[splitChildIdx] 为需要分裂的节点,分裂完后作为        父节点subTree相应位置的左孩子*/    BPlusTreeNode* leftChild = father->subTree[splitChildIdx];    BPlusTreeNode* rightChild = newBPlusTreeNode(true); /* 新分裂出来的节点放在分裂点的右边 */    rightChild->father = father;    int i = 0, mid = M / 2;  // 左孩子mid个key, 右孩子 M-mid个key    if(mid == 1){ // 为了保证至少有两个key        mid++;        if(leftChild->key[mid-1] > key)            mid--;    }        for(; i < M-mid; i++)    {        rightChild->key[i] = leftChild->key[i+mid]; /* 将分裂节点的后M-mid个KEY给右孩子 */    }    memset(&leftChild->key[mid], 0, sizeof(int)*(M-mid)); /* 清空分裂节点后面的M-mid个KEY 值 */    leftChild->keyNum = mid;     rightChild->keyNum = M-mid;    /* 如果该分裂节点不是叶子节点,也就是说它存在子节点        则需要将后面T个子节点送给右节点*/    if(leftChild->isLeaf == false){        rightChild->isLeaf = false;        for(i = 0; i < M-mid; i++){            rightChild->subTree[i] = leftChild->subTree[i+mid];            rightChild->subTree[i]->father = rightChild;        }        /* 同时清除分裂节点的后面T个子节点指针 */ memset(&leftChild->subTree[mid], NULL, sizeof(BPlusTreeNode*) * (M-mid));    }    else{        for(i = 0; i < M-mid; i++){            rightChild->dataAddr[i] = leftChild->dataAddr[i+mid];        }        memset(&leftChild->dataAddr[mid], NULL, sizeof(void*)*(M-mid));    }    int j = father->keyNum;    for(i = father->keyNum-1; i > splitChildIdx; i--){        father->key[j] = father->key[i];        father->subTree[j] = father->subTree[i];        j--;    }    father->key[splitChildIdx] = leftChild->key[0]; /* 将分裂节点的中间KEY 放到父节点的KEY数组中 */    father->key[splitChildIdx+1] =rightChild->key[0];    father->subTree[splitChildIdx+1] = rightChild;    if(father->keyNum == 0)        father->keyNum += 2;    else        father->keyNum++;    return;   }/* sm_key 是pNode 的subTree[index]节点的最小key */void adjustKey(BPlusTreeNode* pNode, int sm_key, int index){    if(!pNode)        return;    if(index != 0){        pNode->key[index] = sm_key;    }    else{        pNode->key[index] = sm_key;        int i = 0;        if(pNode->father != NULL){            for(; i < pNode->father->keyNum; i++){                if(pNode->father->subTree[i] == pNode)                    break;            }            /* 继续向上调整最小key */            adjustKey(pNode->father, sm_key, i);        }    }}/*往节点KEY个数未满的节点处插入key值*/void insertKeyNotFull(BPlusTreeNode* pNode, int key, void* dataAddr){    if(!pNode)        return;    int idx = pNode->keyNum - 1;    if(pNode->isLeaf == true){        if(pNode->keyNum == 0){            pNode->key[0] = key;            pNode->keyNum = 1;            pNode->dataAddr[0] = dataAddr;            return;        }         for(; idx >= 0; idx--)        {            if(key < pNode->key[idx]){                pNode->key[idx+1] = pNode->key[idx];                pNode->dataAddr[idx+1] = pNode->dataAddr[idx];            }            else                break;        }idx = idx + 1;        if(idx == 0){             pNode->key[0] = key;            pNode->dataAddr[0] = dataAddr;            if(pNode->father){                int i = 0;                for(; i < pNode->father->keyNum; i++){                    if(pNode->father->subTree[i] == pNode)                        break;                }                adjustKey(pNode->father, pNode->key[0], i);            }        }else{            pNode->key[idx] = key;            pNode->dataAddr[idx] = dataAddr;        }        pNode->keyNum++;    }    else{        for(idx = pNode->keyNum-1; idx >= 0; idx--){            if(key > pNode->key[idx])                break;        }        if(idx < 0)            idx = 0;                pNode = pNode->subTree[idx];             if(pNode->keyNum >= M){            splitChild(pNode->father, idx, key);            if(pNode->father->subTree[idx+1]->keyNum == 1 ||                 key > pNode->father->key[idx+1])                pNode = pNode->father->subTree[idx+1];        }                insertKeyNotFull(pNode, key, dataAddr);    }    return;}void insertKey(BPlusTreeNode** root, int key, void* dataAddr){    if(*root == NULL){        *root = newBPlusTreeNode(true);    }    BPlusTreeNode* pCur = *root;        if(pCur->keyNum == M){        BPlusTreeNode* newRoot = newBPlusTreeNode(false);        newRoot->subTree[0] = *root;        newRoot->subTree[0]->father = newRoot;        *root = newRoot;        splitChild(newRoot, 0, key);        insertKeyNotFull(newRoot, key, dataAddr);    }    else{        insertKeyNotFull(*root, key, dataAddr);    }    return;}void printKey(int* arry, int n, int layer){    int i = 0;cout << "<" << layer << "> ";    for(; i < n; i++)        printf("%x  ", arry[i]);}static int layer = 1;/* 深度优先遍历: layer 为该节点所在的层*/void DPSearch(BPlusTreeNode* pNode){    if(pNode == NULL)        return;    printKey(pNode->key, pNode->keyNum, layer);    int i = 0;     layer++;    for(; i < pNode->keyNum; i++){DPSearch(pNode->subTree[i]);    }    layer--;    return;}/* 广度优先遍历 */void BPSearch(BPlusTreeNode* pNode){if(pNode == NULL)return;queue<BPlusTreeNode*> q;q.push(pNode);BPlusTreeNode* pCur = NULL;while(!q.empty()){pCur = q.front();printKey(pCur->key, pCur->keyNum, 0);q.pop();int i = 0;for(; i < pCur->keyNum; i++){if(pCur->subTree[i]){q.push(pCur->subTree[i]);}}}}/* 姓名字符串转换为索引键值 */int nameToKey(const char* name){    int len = strlen(name);    int key = 0, n = len-1;        for(; n >= 0; n--){int diff = 0;if(name[n] > '0')diff = name[n] - '0';elsediff = '0' - name[n];        key += diff;    }    return key / len;}BPlusTreeNode* searchKey(BPlusTreeNode* pCur, int key, int* keyIndex){    if(pCur== NULL)        return NULL;    int i = 0;     if(pCur->isLeaf){        for(i = 0; i < pCur->keyNum; i++){            if(pCur->key[i] == key)                break;        }        if(i >= pCur->keyNum)            return NULL;        *keyIndex = i;        return pCur;    }    else{        for(i = pCur->keyNum - 1; i >= 0; i--){            if(key >= pCur->key[i])                break;        }        if(i < 0){            cout << "no match subTree, key = " << key << "; small key = " << pCur->key[0] << endl;            return NULL;        }        return searchKey(pCur->subTree[i], key, keyIndex);    }}void searchInfoByName(BPlusTreeNode* pRoot, const char* name){    if(!pRoot || !name)        return;    int keyIndx = 0, key = 0;    key = nameToKey(name);    BPlusTreeNode* leaf = searchKey(pRoot, key, &keyIndx);    if(leaf){        cout << name << " 的索引key 值为: 0x" << hex << key << endl;        TABLE_ST* personInfo = (TABLE_ST*)leaf->dataAddr[keyIndx];        cout << "年龄: " << dec << personInfo->age << endl;        cout << "家庭住址: " << personInfo->addr << endl;    }    else        cout << "找不到" << name << " 的相关信息" << endl;    return;}BPlusTreeNode* create_BPlusTree(const TABLE_ST* table, int rowNum){    BPlusTreeNode* root = newBPlusTreeNode(true);    //BPlusTreeNode* LeafHead = newBPlusTreeNode(true);    //LeafHead->nextLeaf = root;    if(root){        int i = 0;        for(; i < rowNum; i++){            int key = nameToKey(table[i].name);            insertKey(&root, key, (void*)&table[i]);        }    }    return root;}/* pNode  需要删除的key 在该节点里    isLeft标识找到的兄弟是左兄弟还是右兄弟     index 为pNode 在父节点的subTree数组中的位置    返回值为true 表示找到否则没找到    */bool checkBrotherIsRich(BPlusTreeNode* pNode, int index, bool* isLeft) {    if(pNode == NULL)        return false;    if(pNode->father == NULL)        return false;    BPlusTreeNode* father = pNode->father;    if(index == 0) //如果该节点是最左边的孩子,则只存在右兄弟    {        if(father->subTree[index+1]->keyNum > 2){            *isLeft = false;            return true;        }        else            return false;    }    if(index == father->keyNum-1) //如果该节点是最右边的孩子,则只存在左兄弟    {        if(father->subTree[index-1]->keyNum > 2){            *isLeft = true;            return true;        }        else            return false;    }    /* 一般是先从左兄弟开始判断,移动左兄弟的key        比较方便,不会产生最小key 变化的问题,不需要        向上调整*/    if(index > 0 && index < father->keyNum-1){        if(father->subTree[index-1]->keyNum > 2){            *isLeft = true;            return true;        }        else{            if(father->subTree[index+1]->keyNum > 2){                *isLeft = false;                return true;            }            else                return false;        }    }    return false;}/* 将arry 数组index 后面的内容前移一个单位到index 位置 */template<typename T>void moveProcess(T arry[], int index, int n){    int i = index, j = index + 1;    for(; j < n; j++){        arry[i++] = arry[j];    }    arry[i] = 0;}/* 如果兄弟节点都不富裕,父节点执行合并或旋转操作    sub_idx为需要合并或旋转操作的节点在pNode的subTree[]的index*/void mergeOrRotate(BPlusTreeNode* pNode){    if(!pNode)        return;    if(pNode->father == NULL){ // pNode 为根节点 且 keyNum == 1, 将根节点指针指向子节点        BPlusTreeNode* child = pNode->subTree[0];        /* 将子节点的所有拷贝给根节点 */ int i = 0; for(; i < child->keyNum; i++){ pNode->key[i] = child->key[i];if(child->isLeaf == false){pNode->subTree[i] = child->subTree[i];pNode->subTree[i]->father = pNode;}else{pNode->dataAddr[i] = child->dataAddr[i];pNode->subTree[i] = NULL;} } pNode->keyNum = child->keyNum; free(child); child = NULL;        return;    }    BPlusTreeNode* pFather = pNode->father;    int sub_idx = 0;    for(; sub_idx < pFather->keyNum; sub_idx++){        if(pFather->subTree[sub_idx] == pNode)            break;    }    bool isLeft = false;    if(checkBrotherIsRich(pNode, sub_idx, &isLeft)){        if(isLeft){  // 如果左兄弟富裕 keyNum > 2            /* 将左兄弟的最右的分支借过来(右旋操作) */            BPlusTreeNode* pLeftBrother = pFather->subTree[sub_idx-1];            int i = pNode->keyNum - 1;            for(; i >= 0; i--){                pNode->key[i+1] = pNode->key[i];                pNode->subTree[i+1] = pNode->subTree[i];                //pNode->dataAddr[i+1] = pNode->dataAddr[i];            }            int n = pLeftBrother->keyNum-1;            pNode->key[0] = pLeftBrother->key[n];            pNode->subTree[0] = pLeftBrother->subTree[n];            pNode->subTree[0]->father = pNode;            //pNode->dataAddr[0] = pLeftBrother->dataAddr[n];            pLeftBrother->key[n] = 0;            pLeftBrother->subTree[n] = NULL;            //pLeftBrother->dataAddr[n] = NULL;            pLeftBrother->keyNum--;            pNode->keyNum++;            adjustKey(pFather, pNode->key[0], sub_idx);        }        else{ // 如果右兄弟富裕 keyNum > 2            BPlusTreeNode* pRightBrother = pFather->subTree[sub_idx+1];            int n = pNode->keyNum;            pNode->key[n] = pRightBrother->key[0];            pNode->subTree[n] = pRightBrother->subTree[0];            pNode->subTree[n]->father = pNode;            //pNode->dataAddr[n] = pRightBrother->dataAddr[0];            moveProcess(pRightBrother->key, 0, pRightBrother->keyNum);            moveProcess(pRightBrother->subTree, 0, pRightBrother->keyNum);            //moveProcess(pRightBrother->dataAddr, 0, pRightBrother->keyNum);            pRightBrother->key[pRightBrother->keyNum-1] = 0;            pRightBrother->subTree[pRightBrother->keyNum-1] = NULL;            //pRightBrother->dataAddr[pRightBrother->keyNum-1] = NULL;            pRightBrother->keyNum--;            pNode->keyNum++;            adjustKey(pFather, pRightBrother->key[0], sub_idx+1);        }    }    else{ // 如果左右兄弟都不富裕        /* 将其和左或右兄弟合并             合并将保留左节点*/        BPlusTreeNode* pLeft = NULL, *pRight = NULL;        int keep_id = 0;        if(sub_idx == 0){            pLeft = pNode;            pRight = pFather->subTree[sub_idx+1];            keep_id = sub_idx;        }        else{            pLeft = pFather->subTree[sub_idx-1];            pRight = pNode;            keep_id = sub_idx -1;        }        int n_l = pLeft->keyNum, n_r = pRight->keyNum;        int i = n_l, j = 0;        for(; j < n_r; j++){            pLeft->key[i] = pRight->key[j];            pLeft->subTree[i] = pRight->subTree[j];            pLeft->subTree[i]->father = pLeft;            i++;        }        pLeft->keyNum = i;        moveProcess(pFather->key, keep_id+1, pFather->keyNum);        moveProcess(pFather->subTree, keep_id+1, pFather->keyNum);        pFather->keyNum--;        free(pRight);        pRight = NULL;                /* 如果合并后父节点的keyNum < 2 则递归调用 */        if(pFather->keyNum < 2){            mergeOrRotate(pFather);        }    }        return;}/* pNode 是叶子节点,sub_idx 为其在父节点subTree 中的索引 */void leafMergeAndDelete(BPlusTreeNode* pNode, int sub_idx, int deleteKey){    if(pNode == NULL)        return;    BPlusTreeNode* pFather = pNode->father;    /* 先删除deleteKey */    int oldSmKey = pNode->key[0];    int i = 0, j = 0;    for(; j < pNode->keyNum; j++){        if(pNode->key[j] != deleteKey){            pNode->key[i] = pNode->key[j];            pNode->dataAddr[i] = pNode->dataAddr[j];            i++;        }    }    if(pNode->key[0] != oldSmKey){ //如果最小key 发生变化,调整最小key        adjustKey(pFather, pNode->key[0], sub_idx);    }    pNode->keyNum--;        /* 执行合并操作 */    if(sub_idx == pFather->keyNum-1){ //如果是最右的孩子,就合并到左兄弟去        BPlusTreeNode* pLeftBrother = pFather->subTree[sub_idx-1];        int i = pLeftBrother->keyNum, j = 0;        for(; j < pNode->keyNum; j++){            pLeftBrother->key[i] = pNode->key[j];            pLeftBrother->dataAddr[i] = pNode->dataAddr[j];            i++;        }        pLeftBrother->keyNum = i;        pFather->keyNum--;        pFather->key[pFather->keyNum] = 0;        pFather->subTree[pFather->keyNum] = NULL;        free(pNode);        pNode = NULL;    }    else{ // 把右兄弟合并过来比较方便,不用关心最小key的问题        BPlusTreeNode* pRightBrother = pFather->subTree[sub_idx+1];        int i = pNode->keyNum, j = 0;        for(; j < pRightBrother->keyNum; j++){            pNode->key[i] = pRightBrother->key[j];            pNode->dataAddr[i] = pRightBrother->dataAddr[j];            i++;        }        pNode->keyNum = i;        /* father的sub_idx+1后的key 和subTree指针前移 */        moveProcess(pFather->key, sub_idx+1, pFather->keyNum);        moveProcess(pFather->subTree, sub_idx+1, pFather->keyNum);        pFather->keyNum--;        pFather->key[pFather->keyNum] = 0;        pFather->subTree[pFather->keyNum] = NULL;        free(pRightBrother);        pRightBrother = NULL;    }    /* 合并完后判断父节点的key 个数 */    if(pFather->keyNum < 2){  // case 2.2        mergeOrRotate(pFather);    }    // case 2.1 合并后父节点的key个数任然>= 2则直接结束    return;}/***************************************************************************(1) 如果叶子节点的key 个数大于2,则直接删除即可。(2) 如果不大于2个,则看看其左(右)兄弟(如果存在)是否富裕            case 1: 如果富裕则借一个key, 再删除deleteKey.            case 2: 如果兄弟节点都不富裕,则删除deleteKey 后将其和左(右)                        节点进行合并                  case 2.1: 如果合并后父节点任然富裕,则结束                  case 2.2: 如果合并后父节点的key 个数小于2则递归往上继续                                进行合并操作*********************************************************************************/void deleteKey(BPlusTreeNode* pCur, int deleteKey){    if(!pCur)        return;    int sub_idx = 0;    /* 一直找到叶子节点 */    BPlusTreeNode* pDeleteLeaf = pCur;    while(pDeleteLeaf->isLeaf == false)    {        for(sub_idx = pDeleteLeaf->keyNum - 1; sub_idx >= 0; sub_idx--){            if(deleteKey >= pDeleteLeaf->key[sub_idx])                break;        }        if(sub_idx < 0){            cout << deleteKey << " 不存在" << endl;            return;        }        pDeleteLeaf = pDeleteLeaf->subTree[sub_idx];    }        if(pDeleteLeaf->keyNum > 2){ /* 如果叶子节点的key 个数大于2 直接删除 */        int i = 0, j = 0; int oldSmKey = pDeleteLeaf->key[0];        for(; i < pDeleteLeaf->keyNum; i++)        {            if(pDeleteLeaf->key[i] != deleteKey){                pDeleteLeaf->key[j] = pDeleteLeaf->key[i];                pDeleteLeaf->dataAddr[j] = pDeleteLeaf->dataAddr[i];                j++;            }        } if(j == pDeleteLeaf->keyNum){ cout << deleteKey << " 未找到!!!!!" << endl;return; }        pDeleteLeaf->key[j] = 0;        pDeleteLeaf->dataAddr[j] = NULL;        pDeleteLeaf->keyNum--; if(pDeleteLeaf->key[0] != oldSmKey) adjustKey(pDeleteLeaf->father, pDeleteLeaf->key[0], sub_idx);    }    else{        BPlusTreeNode* pFather = pDeleteLeaf->father;        bool isLeft = false;        if(checkBrotherIsRich(pDeleteLeaf, sub_idx, &isLeft)){ // case 1 如果兄弟节点富裕 key > 2            if(isLeft){  // 如果富裕的是左兄弟                   BPlusTreeNode* pLeftBrother = pFather->subTree[sub_idx-1];                int n = pLeftBrother->keyNum;                int borrowKey = pLeftBrother->key[n-1];  //借用的key                void* addrTmp = pLeftBrother->dataAddr[n-1];                pFather->key[sub_idx] = borrowKey; // 因为是左兄弟,sub_idx不可能是0,所以没必要向上调整最小key                pLeftBrother->key[n-1] = 0;                pLeftBrother->dataAddr[n-1] = NULL;                pLeftBrother->keyNum--;  //兄弟的key个数减一                /* 删除deleteKey */                int i = 1, j = 0;                for(; j < pDeleteLeaf->keyNum; j++){                    if(pDeleteLeaf->key[j] != deleteKey){                        pDeleteLeaf->key[i] = pDeleteLeaf->key[j];                        pDeleteLeaf->dataAddr[i] = pDeleteLeaf->dataAddr[j];                        i++;                    }                }                pDeleteLeaf->key[0] = borrowKey;                pDeleteLeaf->dataAddr[0] = addrTmp;            }else{  // 如果富裕的是右兄弟                BPlusTreeNode* pRightBrother = pFather->subTree[sub_idx+1];                int borrowKey = pRightBrother->key[0];  //借用的key                void* addrTmp = pRightBrother->dataAddr[0];                pFather->key[sub_idx+1] = pRightBrother->key[1];                 int oldSmKey = pDeleteLeaf->key[0];                moveProcess(pRightBrother->key, 0, pRightBrother->keyNum);  //key 前移                moveProcess(pRightBrother->dataAddr, 0, pRightBrother->keyNum);                pRightBrother->keyNum--;  //兄弟的key个数减一                /* 删除deleteKey */                int i = 0, j = 0;                for(; j < pDeleteLeaf->keyNum; j++){                    if(pDeleteLeaf->key[j] != deleteKey){                        pDeleteLeaf->key[i] = pDeleteLeaf->key[j];                        pDeleteLeaf->dataAddr[i] = pDeleteLeaf->dataAddr[j];                        i++;                    }                }                pDeleteLeaf->key[i] = borrowKey;                pDeleteLeaf->dataAddr[i] = addrTmp;                                if(pDeleteLeaf->key[0] != oldSmKey){ //如果最小key 发生变化,调整最小key                    adjustKey(pFather, pDeleteLeaf->key[0], sub_idx);                }            }        }        else{  // case 2 如果兄弟节点不富裕 key <= 2            leafMergeAndDelete(pDeleteLeaf, sub_idx, deleteKey);        }    }    return;}int main(){    BPlusTreeNode* pRoot;    pRoot = create_BPlusTree(peopleInfoTable, 20);    /*        M = 4 的B+树建完后是这样的:                                       4f                              5f                    6c                                      /                                 |                        \                           4f      52     58      5b               5f        64                6c   70                           /        |       |        \           /            \               /       \                      4f 50 51    52 57   58 59    5b 5d      5f 63       64 66 69 6b       6c 6d  70 73 76    */    DPSearch(pRoot);    cout << endl;    searchInfoByName(pRoot, "沈东镇");    searchInfoByName(pRoot, "杨大勇");    searchInfoByName(pRoot, "李正");    searchInfoByName(pRoot, "赵国");        int key = nameToKey("沈东镇");    cout << "删除key = 0x" << hex << key << endl;    deleteKey(pRoot, key);    DPSearch(pRoot);    cout << endl;        /*        删除0x5f 后:                                       4f                              63                    6c                                      /                                 |                        \                           4f      52     58      5b               63        66                6c   70                           /        |       |        \           /            \               /       \                      4f 50 51    52 57   58 59    5b 5d      63 64        66 69 6b         6c 6d  70 73 76    */    searchInfoByName(pRoot, "沈东镇");    key = nameToKey("杨大勇");    cout << "删除key = 0x" << hex << key << endl;    deleteKey(pRoot, key);    DPSearch(pRoot);    cout << endl;        /*        删除0x5b 后:                                       4f                              63                    6c                                      /                                 |                        \                           4f      52     58                      63        66               6c   70                           /        |       |                    /            \              /       \                      4f 50 51    52 57   58 59 5d            63 64         66 69 6b       6c 6d  70 73 76    */    deleteKey(pRoot, 0x52);    cout << "删除key = 0x52" << endl;    DPSearch(pRoot);    cout << endl;    /*        删除0x52 后:                                       4f                              63                    6c                                      /                                 |                        \                           4f      51     58                      63        66               6c   70                           /        |       |                   /            \              /       \                       4f  50     51 57   58 59 5d           63 64        66 69 6b        6c 6d  70 73 76    */    deleteKey(pRoot, 0x64);    cout << "删除key = 0x64" << endl;    DPSearch(pRoot);    cout << endl;        /*        删除0x64 后:                                   4f                              63                    6c                                  /                                 |                        \                       4f      51     58                      63        69                6c   70                       /        |       |                    /            \              /       \                   4f  50     51 57  58 59 5d             63 66          69 6b         6c 6d  70 73 76     */    deleteKey(pRoot, 0x63);    cout << "删除key = 0x63" << endl;    DPSearch(pRoot);    cout << endl;        /*        删除0x63 后:        (1) 合并:                                    4f                  63               6c                                  /                      |                  \                       4f      51     58                66              6c   70                       /        |       |               |              /       \                   4f  50     51 57   58 59 5d       66 69 6b        6c 6d  70 73 76        (2) 旋转:                                4f                  58                  6c                              /                      |                      \                        4f      51              58       66               6c   70                        /        \            /           \              /       \                   4f  50      51 57     58 59 5d     66 69 6b        6c 6d  70 73 76    */deleteKey(pRoot, 0x4f);cout << "删除key = 0x4f" << endl;DPSearch(pRoot);cout << endl;    /*        删除0x4f 后:        (1) 合并: 4f        58      6c   /   |  \     50          58   66    6c   70     |     /   \          /     \      50 51 57         58 59 5d    66 69 6b       6c 6d  70 73 76        (2) 合并:                                    50                                  6c                                    /                                     \                        50       58       66                           6c   70                        /         |          \                        /       \                    50 51 57   58 59 5d    66 69 6b                 6c 6d  70 73 76    */deleteKey(pRoot, 0x50);cout << "删除key = 0x50" << endl;DPSearch(pRoot);cout << endl;/*     删除0x50后:                                    51                                  6c                                    /                                     \                        51       58       66                           6c   70                        /         |          \                         /       \                     51 57     58 59 5d    66 69 6b                6c 6d    70 73 76    */deleteKey(pRoot, 0x66);cout << "删除key = 0x66" << endl;DPSearch(pRoot);cout << endl;/*     删除0x66后:                                    51                                  6c                                    /                                     \                        51       58       69                           6c   70                        /         |          \                        /       \                     51 57    58 59 5d      69 6b                   6c 6d  70 73 76    */       deleteKey(pRoot, 0x69);cout << "删除key = 0x69" << endl;DPSearch(pRoot);cout << endl;/*     删除0x69后:                                    51                                  6c                                    /                                     \                        51       58       5d                           6c   70                        /         |          \                        /       \                     51 57      58 59      5d 6b                    6c 6d  70 73 76    */       deleteKey(pRoot, 0x5d);cout << "删除key = 0x5d" << endl;DPSearch(pRoot);cout << endl;/*     删除0x5d后:                                    51                         6c                                    /                             \                         51          58                         6c   70                        /             \                        /       \                     51 57          58 59 6b                 6c 6d  70 73 76    */       deleteKey(pRoot, 0x57);cout << "删除key = 0x57" << endl;DPSearch(pRoot);cout << endl;/*     删除0x57后:                                    51                         6c                                    /                             \                         51          59                         6c   70                        /             \                        /       \                      51 58         59 6b                    6c 6d  70 73 76    */       deleteKey(pRoot, 0x58);cout << "删除key = 0x58" << endl;DPSearch(pRoot);cout << endl;/*     删除0x58后:                                    51             6c           70                                    /               |              \                                51 59 6b         6c 6d          70 73 76    */        deleteKey(pRoot, 0x6d);cout << "删除key = 0x6d" << endl;DPSearch(pRoot);cout << endl;/*     删除0x6d后:                                    51             6b           70                                    /               |              \                                   51 59          6b 6c         70 73 76    */deleteKey(pRoot, 0x6b);cout << "删除key = 0x6b" << endl;DPSearch(pRoot);cout << endl;/*     删除0x6b后:                                    51          6c        73                                    /           |          \                                   51 59      6c 70       73 76    */deleteKey(pRoot, 0x76);cout << "删除key = 0x76" << endl;DPSearch(pRoot);cout << endl;/*     删除0x76后:                                    51        6c                                            /           \                                            51 59      6c 70 73          */deleteKey(pRoot, 0x51);cout << "删除key = 0x51" << endl;DPSearch(pRoot);cout << endl;/*     删除0x51后:                                    59        70                                            /           \                                            59 6c      70 73          */deleteKey(pRoot, 0x6c);cout << "删除key = 0x6c" << endl;DPSearch(pRoot);cout << endl;/*     删除0x6c后:  59 70 73     */    return 0;}


运行结果:


0 0
原创粉丝点击