算法导论 B树(附带节点高度)

#include <stdio.h>
#include <stdlib.h>

#define t 3

typedef struct BNodeType
{
    int n;
    char key[2*t];
    bool leaf;
    BNodeType *c[2*t+1];
    int height;
}BNode,*pBNode;

typedef struct
{
    pBNode root;
}bTree,*pBTree;

typedef struct 
{
    pBNode x;
    int i;
}sType,*pStype;

pBNode allocateNode()
{
    pBNode node=(pBNode)malloc(sizeof(BNode));
    node->n=0;
    node->height=0;
    return node;
}

void b_tree_create(pBTree T)
{
    pBNode x=allocateNode();
    x->leaf=true;
    x->n=0;
    x->height=0;
    T->root=x;
}



void b_tree_split_child(pBNode x,int i)
{
    pBNode z=allocateNode();
    pBNode y=x->c[i];
    z->leaf=y->leaf;
    z->height=y->height;
    z->n=t-1;
    for(int j=1;j<=t-1;j++)
    {
        z->key[j]=y->key[j+t];
    }
    if(!y->leaf)
    {
        for(int j=1;j<=t;j++)
        {
            z->c[j]=y->c[j+t];
        }
    }
    y->n=t-1;
    for(int j=x->n+1;j>=i+1;j--)
    {
        x->c[j+1]=x->c[j];
    }
    x->c[i+1]=z;
    for(int j=x->n;j>=i;j--)
    {
        x->key[j+1]=x->key[j];
    }
    x->key[i]=y->key[t];
    x->n++;
}

void b_tree_insert_nonfull(pBNode x, char k)
{
    int i=x->n;
    if(x->leaf)
    {
        while(i>=1 && k<x->key[i])
        {
            x->key[i+1]=x->key[i];
            i--;
        }
        x->key[i+1]=k;
        x->n++;
    }
    else
    {
        while(i>=1 && k<x->key[i])
        {
            i--;
        }
        i++;
        if(x->c[i]->n==2*t-1)
        {
            b_tree_split_child(x,i);
            if(k>x->key[i])
                i++;
        }
        b_tree_insert_nonfull(x->c[i],k);
    }
}

void b_tree_insert(pBTree T,char k)
{
    pBNode r=T->root;
    if(r->n==2*t-1)
    {
        pBNode s=allocateNode();
        T->root=s;
        s->leaf=false;
        s->n=0;
        s->height=r->height+1;
        s->c[1]=r;
        b_tree_split_child(s,1);
        b_tree_insert_nonfull(s,k);
    }
    else
        b_tree_insert_nonfull(r,k);
}

pStype b_tree_search(pBNode x,char k)
{
    int i=1;
    while(i<=x->n && k>x->key[i])
        i++;
    if(k==x->key[i])
    {
        pStype s=(pStype)malloc(sizeof(sType));
        s->x=x;
        s->i=i;
        return s;
    }
    else if(x->leaf)
        return NULL;
    else
        return b_tree_search(x->c[i],k);
}

//这个前驱函数假设x为非叶节点,包含叶节点的前驱函数需要用到父节点,这里用不到所以没写
char preDecessor(pBNode x,int i)
{
    pBNode y=x->c[i];
    while(y && !y->leaf)
        y=y->c[y->n+1];
    return y->key[y->n];
}

//这个后继函数假设x为非叶节点,包含叶节点的后继函数需要用到父节点,这里用不到所以没写
char successor(pBNode x,int i)
{
    pBNode y=x->c[i+1];
    while(y && !y->leaf)
        y=y->c[1];
    return y->key[1];
}

void b_tree_delete(pBNode x,char k,pBTree T)
{
    int i=1;
    while(i<=x->n && k>x->key[i])
        i++;
    if(k==x->key[i])
    {
        //case 1
        if(x->leaf)
        {
            for(int j=i;j<x->n;j++)
            {
                x->key[j]=x->key[j+1];
            }
            x->n--;
        }
        //case 2
        else
        {
            //case 2.a
            pBNode y=x->c[i],z=x->c[i+1];
            if(y->n>=t)
            {
                char pre=preDecessor(x,i);
                x->key[i]=pre;
                b_tree_delete(x->c[i],pre,T);
            }
            //case 2.b
            else if(z->n>=t)
            {
                char suc=successor(x,i);
                x->key[i]=suc;
                b_tree_delete(x->c[i+1],suc,T);
            }
            //case 2.c
            else
            {			
                //处理y中key数组
                int j=y->n+1;
                y->key[j]=x->key[i];
                for(int m=1;m<=z->n;m++)
                {
                    y->key[j+m]=z->key[m];
                }
                //处理y子节点
                j=y->n+1;
                for(int m=1;m<=z->n+1;m++)
                {
                    y->c[j+m]=z->c[m];
                }
                //处理y中key的个数
                y->n+=z->n+1;
                
                //处理x中key数组
                for(int m=i;m<x->n;m++)
                    x->key[m]=x->key[m+1];
                //处理x子节点
                for(int m=i+1;m<x->n+1;m++)
                    x->c[m]=x->c[m+1];
                //处理x中key的个数
                x->n--;

                if(x->n==0)
                {
                    free(x);
                    T->root=y;
                }
                free(z);
                b_tree_delete(y,k,T);
            }
        }
    }
    //case 3
    else
    {		
        pBNode y=x->c[i];
        if(y->n<t)
        {
            //case 3.a
            if(i>1 && x->c[i-1] && x->c[i-1]->n>=t)
            {
                //z是y的左兄弟
                pBNode z=x->c[i-1];
                char lc=z->key[z->n];
                char xc=x->key[i-1];
                //处理x
                x->key[i-1]=lc;				
                //处理y
                for(int m=y->n;m>=1;m--)
                {
                    y->key[m+1]=y->key[m];
                }
                y->key[1]=xc;
                for(int m=y->n+1;m>=1;m--)
                {
                    y->c[m+1]=y->c[m];
                }
                y->c[1]=z->c[z->n+1];
                y->n++;
                //处理z
                z->n--;
                
            }
            else if(i<x->n+1 && x->c[i+1] && x->c[i+1]->n>=t)
            {
                //z是y的右兄弟
                pBNode z=x->c[i+1],y=x->c[i];
                char rc=z->key[1];
                char xc=x->key[i];
                //处理x
                x->key[i]=rc;				
                //处理y
                y->key[y->n+1]=xc;
                y->c[y->n+2]=z->c[1];
                y->n++;
                //处理z
                for(int m=1;m<z->n;m++)
                {
                    z->key[m]=z->key[m+1];
                }
                for(int m=1;m<z->n+1;m++)
                {
                    y->c[m]=y->c[m+1];
                }				
                z->n--;
            }
            //case 3.b
            else
            {
                if(i>1 && x->c[i-1] && x->c[i-1]->n<t)
                {
                    //z是y的左兄弟
                    pBNode z=x->c[i-1];
                    //处理y中key数组
                    for(int m=y->n;m>=1;m--)
                        y->key[m+t]=y->key[m];					
                    for(int m=1;m<=z->n;m++)
                    {
                        y->key[m]=z->key[m];
                    }
                    y->key[t]=x->key[i-1];
                    //处理y子节点
                    for(int m=y->n+1;m>=1;m--)
                        y->c[m+t]=y->c[m];	
                    for(int m=1;m<=z->n+1;m++)
                    {
                        y->c[m]=z->c[m];
                    }
                    //处理y中key的个数
                    y->n+=z->n+1;
                
                    //处理x中key数组
                    for(int m=i-1;m<x->n;m++)
                        x->key[m]=x->key[m+1];
                    //处理x子节点
                    for(int m=i-1;m<x->n+1;m++)
                        x->c[m]=x->c[m+1];
                    //处理x中key的个数
                    x->n--;

                    if(x->n==0)
                    {
                        free(x);
                        T->root=y;
                    }
                    free(z);
                }
                else if(i<x->n+1 && x->c[i+1] && x->c[i+1]->n<t)
                {
                    //z是y的右兄弟
                    pBNode z=x->c[i+1];
                    //处理y中key数组	
                    y->key[t]=x->key[i];
                    for(int m=1;m<=z->n;m++)
                    {
                        y->key[m+t]=z->key[m];
                    }				
                    //处理y子节点
                    for(int m=1;m<=z->n+1;m++)
                    {
                        y->c[m+t]=z->c[m];
                    }
                    //处理y中key的个数
                    y->n+=z->n+1;
                
                    //处理x中key数组
                    for(int m=i;m<x->n;m++)
                        x->key[m]=x->key[m+1];
                    //处理x子节点
                    for(int m=i+1;m<x->n+1;m++)
                        x->c[m]=x->c[m+1];
                    //处理x中key的个数
                    x->n--;

                    if(x->n==0)
                    {
                        free(x);
                        T->root=y;
                    }
                    free(z);
                }
            }
        }	
        b_tree_delete(y,k,T);
    }
    
}

void printNode(pBNode x)
{
    for(int i=1;i<=x->n;i++)
    {
        printf("%c,%d ",x->key[i],x->height);
    }
    printf("\n");
}

pBTree initTree()
{
    pBTree T=(pBTree)malloc(sizeof(bTree));	
    T->root=allocateNode();
    pBNode x=T->root;
    x->n=4;
    x->height=1;
    x->leaf=false;
    x->key[1]='G';
    x->key[2]='M';
    x->key[3]='P';
    x->key[4]='X';
    pBNode c1=allocateNode();
    c1->n=4;
    c1->height=0;
    c1->leaf=true;
    c1->key[1]='A';
    c1->key[2]='C';
    c1->key[3]='D';
    c1->key[4]='E';
    pBNode c2=allocateNode();
    c2->n=2;
    c2->height=0;
    c2->leaf=true;
    c2->key[1]='J';
    c2->key[2]='K';
    pBNode c3=allocateNode();
    c3->n=2;
    c3->height=0;
    c3->key[1]='N';
    c3->key[2]='O';
    pBNode c4=allocateNode();
    c4->n=5;
    c4->height=0;
    c4->key[1]='R';
    c4->key[2]='S';
    c4->key[3]='T';
    c4->key[4]='U';
    c4->key[5]='V';
    pBNode c5=allocateNode();
    c5->n=2;
    c5->height=0;
    c5->key[1]='Y';
    c5->key[2]='Z';
    x->c[1]=c1;
    x->c[2]=c2;
    x->c[3]=c3;
    x->c[4]=c4;
    x->c[5]=c5;
    return T;
}

void main()
{
    pBTree T=initTree();
    b_tree_insert(T,'B');
    b_tree_insert(T,'Q');
    b_tree_insert(T,'L');
    b_tree_insert(T,'F');
    b_tree_delete(T->root,'F',T);
    b_tree_delete(T->root,'M',T);
    b_tree_delete(T->root,'G',T);
    //b_tree_delete(T->root,'D',T);
    //b_tree_delete(T->root,'B',T);
    pStype s;
    s=b_tree_search(T->root,'P');
    printNode(s->x);
    s=b_tree_search(T->root,'C');
    printNode(s->x);
    s=b_tree_search(T->root,'E');
    printNode(s->x);
    getchar();
}

    原文作者:B树
    原文地址: https://blog.csdn.net/niewei1986/article/details/73935659
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞