B树的插入和删除

来源:互联网 发布:网络上bgm是什么意思 编辑:程序博客网 时间:2024/05/22 10:38

B-Tree 翻译过来为: B树,B-树
下面代码可以直接运行,我思路还是简单,就是调代码花了好久
供大家参考(除了结构体定义以外,没有参考任何网站,纯自己的思路)

#include<iostream>#include <vld.h>#include <queue>using namespace std;#define M 5  //奇数#define MAXNUM (M-1)#define MINNUM (M/2)#define KeyType charclass BNode;typedef struct{    BNode *pnode;    int index;    bool tag;}Result;typedef struct{} Record;typedef struct{    KeyType key;    Record *recptr;}ElemType;class BNode{public:    BNode(ElemType et)    {        data[1] = et;        num = 1;        parent = NULL;        for (int i = 0; i <= M; i++)            sub[i] = NULL;    }    BNode(BNode *left, int first, int end)    {        num = end - first + 1;        parent = NULL;        /*改sub*/        for (int i = 0; i <= num; i++)        {            sub[i] = NULL;            if (left->sub[first - 1 + i])            {                sub[i] = left->sub[first - 1 + i];                left->sub[first - 1 + i]->parent = this;            }        }        for (int i = 1; i <= num; i++)            data[i] = left->data[first++];    }    ~BNode(){}public:    int num;    BNode *parent;    ElemType data[M + 1];    BNode *sub[M + 1];};class BTree{private:    BNode *root;public:    BTree() :root(NULL){}    Result findValue(KeyType kx)    {        ////////////////////////////////////LaoYang Programing////////////////////////////////////////////////        Result res = { NULL, -1, false };        BNode *ptr = root;        while (ptr)        {            ptr->data[0].key = kx;            int i = ptr->num;            while (kx < ptr->data[i].key)                --i;            res.pnode = ptr;            res.index = i;            if (i > 0 && ptr->data[i].key == kx)            {                res.tag = true;                break;            }            ptr = ptr->sub[i];        }        return res;    }    Result SearchValue(BNode *ptr, KeyType kx)    {        Result res = { NULL, -1, false };        if (ptr != NULL)        {            ptr->data[0].key = kx;            int i = ptr->num;            while (kx < ptr->data[i].key)                i--;            res.index = i;            res.pnode = ptr;            if (i > 0 && ptr->data[i].key == kx)                res.tag = true;            else if (ptr->sub[i])                res = SearchValue(ptr->sub[i], kx);        }        return res;    }    bool Insert(ElemType et)    {        if (root == NULL)        {            root = new BNode(et);            return true;        }        //Result res = SearchValue(root, et.key);         Result res = findValue(et.key);        if (res.tag)            return false;        BNode *pa = res.pnode;        //把数据插入到node中        insert_data(pa, et);        if (pa->num == M)//如果已经满了            split(pa);//要分裂        return true;    }    void split(BNode *node)    {        if (node)        {            //改变原节点            node->num = 2;            //创建右节点            BNode *right = new BNode(node, M / 2 + 2, M);            BNode *pa = node->parent;            /*分裂到了root*/            if (!pa)            {                BNode *newRoot = new BNode(node->data[M / 2 + 1]);                newRoot->sub[0] = node;                newRoot->sub[1] = right;                node->parent = newRoot;                right->parent = newRoot;                node->num = M / 2;                root = newRoot;            }            else //没有分裂到root            {                //把et插入到父节点数据域中                int index = insert_data(pa, node->data[3]);                pa->sub[index] = right;                right->parent = pa;                //判断是否需要向上继续分裂                if (pa->num > MAXNUM)                    split(pa);            }        }    }    int insert_data(BNode *node, ElemType et)    {        int i = node->num;        while (node->data[i].key > et.key && i > 0)        {            node->data[i + 1] = node->data[i];            node->sub[i + 1] = node->sub[i];            i--;        }        node->data[i + 1] = et;        node->sub[i + 1] = NULL;        node->num++;        return i + 1;    }    void InOrder(BNode *ptr)    {        if (ptr)        {            InOrder(ptr->sub[0]);            for (int i = 1; i <= ptr->num; i++)            {                cout << ptr->data[i].key << "  ";                InOrder(ptr->sub[i]);            }        }    }    void InOrder()    {        InOrder(root);    }    void layer_print()    {        queue<BNode*> q;        BNode* node;        if (!root)        {            cout << "没有节点了" << endl;            return;        }        q.push(root);        while (!q.empty())        {            node = q.front();            q.pop();            for (int i = 0; i <= node->num; i++)            {                if (node->sub[i])                    q.push(node->sub[i]);            }            for (int i = 1; i <= node->num; i++)                cout << node->data[i].key << "  ";            cout << endl;        }    }    //////////////////////////////删除//////////////////////////////////////////////    bool Remove(ElemType et)    {        if (!root) return false;        Result res = findValue(et.key);        BNode *node = res.pnode;        BNode *pre = FindPrev(node, res.index);        BNode *next = FindNext(node, res.index);        BNode *adjNode = remove_key(node,pre,next,res.index,et.key);        if (adjNode->parent && adjNode->num < MINNUM)            Adjust_Leaf(adjNode);        else if (!adjNode->parent && !adjNode->num)        {            delete root;            root = NULL;        }    }    void remove_key_pre(BNode *node, BNode *pre, int index, KeyType k)    {        node->data[index] = pre->data[pre->num];        pre->num--;    }    void remove_key_next(BNode *node, BNode *next, int index, KeyType k)    {        node->data[index] = next->data[1];        for (int i = 1; i < next->num; i++)            next->data[i] = next->data[i + 1];        next->num--;    }    BNode* remove_key(BNode *node, BNode *pre, BNode *next, int index, KeyType k)    {        if (pre && pre->num > MINNUM)        {            remove_key_pre(node, pre, index, k);            return pre;        }        else if (next && next->num > MINNUM)        {            remove_key_next(node, next, index, k);            return next;        }        else if (pre)        {            remove_key_pre(node, pre, index, k);            return pre;        }        else if (next)        {            remove_key_next(node, next, index, k);            return next;        }        else        {            //叶节点            while (index != node->num)            {                node->data[index] = node->data[index + 1];                index++;            }            node->num--;            return node;        }    }    BNode *FindPrev(BNode *ptr,int index)    {        if (ptr = ptr->sub[index - 1])        {            while (ptr->sub[ptr->num])                ptr = ptr->sub[ptr->num];            return ptr;        }        return NULL;    }    BNode *FindNext(BNode *ptr, int index)    {        if (ptr = ptr->sub[index])        {            while (ptr->sub[0])                ptr = ptr->sub[0];            return ptr;        }        return NULL;    }    void borrow_left(BNode *node, BNode *left,BNode *pa,int index)    {        node->data[0] = pa->data[index];        pa->data[index] = left->data[left->num];        for (int i = node->num; i >= 0; i--)        {            node->data[i + 1] = node->data[i];            node->sub[i + 1] = node->sub[i];        }        node->sub[0] = left->sub[left->num];        if (left->sub[left->num])            left->sub[left->num]->parent = node;        node->num++;        left->num--;    }    void borrow_right(BNode *node, BNode *right, BNode *pa, int index)    {        node->data[node->num + 1] = pa->data[index];        pa->data[index] = right->data[0];        node->sub[node->num + 1] = right->sub[0];        if (right->sub[0])            right->sub[0]->parent = node;        for (int i = 1; i < right->num; i++)            right->data[i] = right->data[i + 1];        for (int i = 0; i < right->num; i++)            right->sub[i] = right->sub[i + 1];        node->num++;        right->num--;    }    void mergeNode(BNode *left,BNode *right,BNode* pa, int index)    {        if (!left)            left = new BNode(pa->data[index + 1]);        else            left->data[++left->num] = pa->data[index + 1];        int num = left->num;        if (right)        {            //调整left兄弟            for (int i = 1; i <= right->num; i++)                left->data[num + i] = right->data[i];            for (int i = 0; i <= right->num; i++)            {                left->sub[num + i] = right->sub[i];                if (right->sub[i])                    right->sub[i]->parent = left;            }            left->num += right->num;        }        //调整父节点        if (pa->num == 1)        {            //这时候要换根节点            left->parent = NULL;            root = left;            //不能在里面删除当前root            //delete pa;            //pa = NULL;            pa->num = -1;//标记        }        else        {            for (int i = index + 1; i < pa->num; i++)            {                pa->data[i] = pa->data[i + 1];                pa->sub[i] = pa->sub[i + 1];            }            pa->num--;        }        delete right;    }    void Adjust_Leaf(BNode *node)    {        BNode *leftBro = NULL, *rightBro = NULL, *parent = NULL;        parent = node->parent;        //找出node在父节点中的index        int index = find_index(node,parent);        if (index - 1 >= 0)            leftBro = parent->sub[index - 1];        if (index + 1 <= node->num)            rightBro = parent->sub[index + 1];        if (index - 1 < 0)        {            //没有左兄弟   向右借            if (rightBro->num > MINNUM)                borrow_right(node, rightBro, parent, index);            //右兄弟没钱,和右兄弟合并            else                mergeNode(node, rightBro, parent, index);        }        else if (index + 1 <= MAXNUM)        {            //没有右兄弟   向左借            if (leftBro->num > MINNUM)                borrow_left(node, leftBro, parent, index);            //左兄弟没钱,和左兄弟合并            else                mergeNode(leftBro, node, parent, index - 1);        }        else        {            //有两兄弟,优先向左借            if (leftBro->num > MINNUM)                borrow_left(node, leftBro, parent, index);            else if (rightBro->num > MINNUM)                borrow_right(node, rightBro, parent, index);            else                mergeNode(leftBro, node, parent, index);        }        if (parent->num == -1)        {            delete parent;            parent = NULL;            return;        }        if (parent->num < MINNUM && parent->parent)            Adjust_Leaf(parent);    }    //找出ptr在父节点中的index    int find_index(BNode *ptr, BNode *pa)    {        KeyType min = ptr->data[1].key;        int i;        for (i = 1; i <= pa->num; i++)        {            if (min < pa->data[i].key)            {                return i - 1;            }        }        return i - 1;    }};int main(){    KeyType ar[] = "QWERTYUIOPASDFGHJKLZXCVBNM";    int n = sizeof(ar) / sizeof(ar[0]) - 1;    ElemType item;    BTree root;    for (int i = 0; i < n; i++)    {        item.key = ar[i];        item.recptr = NULL;        root.Insert(item);        root.InOrder();        /*cout << "★★" << endl;        root.layer_print();*/        cout << endl << "------------------------------------添加--------------------------------------" << ar[i] << endl;    }    for (int i = 0; i < n; i++)    {        item.key = ar[i];        item.recptr = NULL;        root.Remove(item);        root.InOrder();        /*cout << "★★" << endl;        root.layer_print();*/        cout << endl << "------------------------------------删除--------------------------------------" << ar[i] << endl;    }    system("pause");}
0 0
原创粉丝点击