zoukankan      html  css  js  c++  java
  • 数据结构实现B树




    #include<stdio.h>
    #include<stdlib.h>
    #define m 4//const int m=4; B树的阶树
    #define Max 3//const int Max=m-1;最大的关键字个数
    #define Min 1.5//const int Min=(m-1)/2;最小的关键字个数
    using namespace std;
    
    /**抽象类型函数
    void init(t);                                       //初始化B树
    void searchBTree(BTree t,int k,result &r);          //在B树中查找关键字k,r.tag==1为找到
                                                        //r.tag==0为找不到
    void search(BTree p,int k);                         //在结点p中找关键字k的位置
    void newBTreeroot(BTree &t,BTree p,int k,BTree q);  //新建根节点t
    void insertBTree(BTree &t,int k);                   //在B中加入关键字k
    void insert(BTree p,int k,BTree ap,int i);          //在p结点中插入关键字k
    void spilt(BTree p,BTree ap,int s);                 //将结点以位置s为中心拆成两部分
    Remove(BTree p,int k);                              //在结点p中删除关键字k
    void findNode(BTree p,int k,int &i);                //在结点p中寻找k的位置
    void deleteBTree(BTree t,int k);                    //在B树中删除关键字k
    int deleteNode(BTree p,int k);                      //在B树删除操作的总接口
    void substitution(BTree p,int i);                   //向右子树借最小值
    void adjustBTree(BTree p,int i);                    //结点长度小于Min进行调整
    void leftMove(BTree p,int i);                       //向右结点借值
    void rightMove(BTree p,int i);                      //向左结点借值
    void combine(BTree p,int i);                        //左右不够借,合并三个元素
    void DestoryBTree(BTree &t);                        //销毁B树
    void printBTree(BTree t);                           //用队列输出B树
    void printarray(int k);                           //升序输出B树元素
    **/
    
    /**B树的抽象实现**/
    typedef struct rt{          //定义结点信息
        int key[m+1];           //结点关键字数组,key[0]不用
        int keynum;             //结点关键字个数
        struct rt* parent;      //双亲结点指针
        struct rt* ptr[m+1];    //孩子结点指针
    }BNT,*BTree;
    
    typedef struct op{          //查找结果
        int i;                  //结点的关键字位置或需插入位置
        int tag;                //成功与否标志
        BTree pt;               //找到的结点
    }result;
    
    typedef struct qp{          //模拟队列
        BTree pt;               //指向B树结点(数据域)
        struct qp* next;        //下一个队列指针(指针域)
    }queueBNT,*queueBTree;
    
    int search(BTree p,int k) { //在子树p中寻找结点k
        int i=1;
        while(i<=p->keynum&&p->key[i]<k)i++;
        return i;
    }
    
    void init(BTree &t){         //初始化B树
        t==NULL;
    }
    
    void searchBTree(BTree t,int k,result &r) { //在B树t中查找结点
        int finshed=0,i=0;
    
        BTree p=t,q=NULL;
        while(p!=NULL&&finshed==0) {
            i=search(p,k);
            if(i<=p->keynum&&p->key[i]==k)finshed=1;
            else {
                q=p;
                p=p->ptr[i-1];
            }
        }
        if(finshed==1) {                         //找到结点
            r.tag=1; r.i=i; r.pt=q;
        }
        else {                                   //找不到结点
            r.tag=0; r.i=i; r.pt=q;
        }
    }
    
    void newBTreeroot(BTree &t,BTree p,int k,BTree aq) {
        t=(BTree)malloc(sizeof(BNT));
        t->key[1]=k; t->keynum=1;
        t->ptr[0]=p; t->ptr[1]=aq;
        if(p!=NULL)p->parent=t;
        if(aq!=NULL)aq->parent=t;
        t->parent=NULL;
    }
    
    void insert(BTree p,int k,BTree &ap,int i) {
        int j;
        for(j=p->keynum;j>=i;j--) {
            p->key[j+1]=p->key[j];
            p->ptr[j+1]=p->ptr[j];
        }
        p->key[i]=k; p->ptr[i]=ap;
        if(ap!=NULL)ap->parent=p;
        p->keynum++;
    }
    
    void spilt(BTree p,BTree &ap,int s) {
        int i,j;
        ap=(BTree)malloc(sizeof(BNT));
        ap->ptr[0]=p->ptr[s];
        for(j=s+1,i=1;j<=p->keynum;i++,j++) {
            ap->key[i]=p->key[j];
            ap->ptr[i]=p->ptr[j];
        }
        ap->keynum=p->keynum-s;
        ap->parent=p->parent;
        for(i=0;i<=ap->keynum;i++) {
            if(ap->ptr[i]!=NULL)ap->ptr[i]->parent=ap;
        }
        p->keynum=s-1;
    }
    
    void insertBTree(BTree &t,int k) {//在B树中添加k关键字
        result r;
        searchBTree(t,k,r);
        if(r.tag==1)return ;//关键字已经存在
        BTree p=r.pt; int i=r.i;
        BTree ap; int x,s,finshed,needNewroot;
        x=k; ap=NULL; finshed=needNewroot=0;
        if(p==NULL) newBTreeroot(t,NULL,k,NULL);
        else {
            while(finshed==0&&needNewroot==0) {
                insert(p,x,ap,i);
                if(p->keynum<=Max)finshed=1;
                else {
                    s=(m+1)>>1; spilt(p,ap,s);
                    x=p->key[s];
                    if(p->parent!=NULL) {
                        p=p->parent;
                        i=search(p,x);
                    }
                    else needNewroot=1;
                }
            }
            if(needNewroot==1) newBTreeroot(t,p,x,ap);
        }
    }
    
    void findNode(BTree p,int k,int &i) {
        i=p->keynum;
        while(i>0&&p->key[i]>k)i--;
    }
    
    void substitution(BTree p,int i) {
        BTree ap=p->ptr[i];
        while(ap->ptr[0]){
            ap=ap->ptr[0];
        }
        p->key[i]=ap->key[1];
    }
    
    void remove(BTree p,int i) {
        int j;
        p->keynum--;
        for(j=i;j<=p->keynum;j++) {
            p->key[j]=p->key[j+1];
            p->ptr[j]=p->ptr[j+1];
        }
    }
    
    void leftMove(BTree p,int i) {
        int j;
        BTree q=p->ptr[i-1],ap=p->ptr[i];
        q->keynum++;
        q->key[q->keynum]=p->key[i];
        q->ptr[q->keynum]=ap->ptr[0];
        if(ap->ptr[0]!=NULL)ap->ptr[0]->parent=p->ptr[i-1];
    
        p->key[i]=ap->key[1];
        ap->ptr[0]=ap->ptr[1];
        ap->keynum--;
        for(j=1;j<=ap->keynum;j++) {
            ap->key[j]=ap->key[j+1];
            ap->ptr[j]=ap->ptr[j+1];
        }
    }
    
    void rightMove(BTree p,int i) {
        int j;
        BTree q=p->ptr[i-1],ap=p->ptr[i];
        ap->keynum++;
        for(j=ap->keynum;j>1;j--){
            ap->key[j]=ap->key[j-1];
            ap->ptr[j]=ap->ptr[j-1];
        }
        ap->key[1]=p->key[i]; ap->ptr[1]=ap->ptr[0];
        ap->ptr[0]=q->ptr[q->keynum];
        if(q->ptr[q->keynum]!=NULL)q->ptr[q->keynum]->parent=p->ptr[i];
    
        p->key[i]=q->key[q->keynum];
        q->keynum--;
    }
    
    void combine(BTree p,int i) {
        int j,k;
        BTree q=p->ptr[i-1],ap=p->ptr[i];
        j=q->keynum;
        q->key[++j]=p->key[i];q->ptr[j]=ap->ptr[0];
        for(k=1;k<=ap->keynum;k++){
            q->key[++j]=ap->key[k];
            q->ptr[j]=ap->ptr[k];
        }
        for(k=q->keynum+1;k<=j;k++){
            if(q->ptr[k]!=NULL)q->ptr[k]->parent=p->ptr[i-1];
        }
        q->keynum=j;
    
        p->keynum--;
        for(j=i;j<=p->keynum;j++){
            p->key[j]=p->key[j+1];
            p->ptr[j]=p->ptr[j+1];
        }
        free(ap);
    }
    
    void adjustBTree(BTree p,int i) {
        if(i==0){
            if(p->ptr[1]->keynum>Min)leftMove(p,1);
            else combine(p,1);
        }
        else if(i==p->keynum) {
            if(p->ptr[i-1]->keynum>Min)rightMove(p,i);
            else combine(p,i);
        }
        else {
            if(p->ptr[i-1]->keynum>Min)rightMove(p,i);
            else if(p->ptr[i+1]->keynum>Min)leftMove(p,i+1);
            else combine(p,i);
        }
    }
    
    int deleteNode(BTree p,int k) {
        if(p==NULL)return 0;
        int i,flag=0;
        findNode(p,k,i);
        if(i>0&&p->key[i]==k) {
            flag=1;
            if(p->ptr[i-1]!=NULL) {
                substitution(p,i);
                deleteNode(p->ptr[i],p->key[i]);
            }
            else {
                remove(p,i);
            }
        }
        else flag=deleteNode(p->ptr[i],k);
        if(flag){
            if(p->ptr[i]!=NULL) {
                if(p->ptr[i]->keynum<Min) {
                    adjustBTree(p,i);
                }
            }
        }
        return flag;
    }
    
    int deleteBTree(BTree &t,int k) {//删除操作
        int flag;
        BTree p;
        flag=deleteNode(t,k);
        if(flag==0)return 0;//该关键字不在t中
        if(t->keynum==0){
            p=t;t=t->ptr[0];free(p);
    	t->parent=NULL;
        }
        return 1;
    }
    
    void DestoryBTree(BTree &t){
        if(t==NULL)return;
        int i;
        BTree p;
        queueBTree pl,pr,ap,q;
        pl=(queueBTree)malloc(sizeof(queueBNT));
        pr=(queueBTree)malloc(sizeof(queueBNT));
        pl->pt=t; pl->next=NULL; pr=pl;
        while(pl){
            p=pl->pt;
            for(i=0;i<=p->keynum;i++){
                if(p->ptr[i]){
                    ap=(queueBTree)malloc(sizeof(queueBNT));
                    ap->pt=p->ptr[i]; ap->next=NULL;
                    pr->next=ap; pr=ap;
                }
            }
            q=pl;
            pl=pl->next;
            free(q->pt);
            free(q);
            q=NULL;
        }
        t=NULL;
    }
    
    void printBTree(BTree t){
        if(t==NULL){
            printf("
    ");
            printf("BTree is empty.");
            printf("
    ");
        }
        else {
            int i,j;
            BTree p;
            queueBTree root,pl,pr,ap,q,dp;
            pl=(queueBTree)malloc(sizeof(queueBNT));
            root=pl;
            pl->pt=t; pl->next=NULL; pr=pl;
            p=pl->pt;
            printf("[ ");
            for(i=1;i<=t->keynum;i++){
                printf("%d ",p->key[i]);
            }
            printf("]
    ");
            dp=pl;
            int flag=1;
            while(pl){
                p=pl->pt;
                if(flag&&p->ptr[0]==NULL&&p!=t){
                    while(dp!=NULL&&dp->pt!=p){
                        BTree tmp=dp->pt;
                        for(i=0;i<=tmp->keynum;i++){
                            printf("[ ");
                            for(j=1;j<=tmp->ptr[i]->keynum;j++){
                                printf("%d ",tmp->ptr[i]->key[j]);
                            }
                            printf("] ");
                        }
                        dp=dp->next;
                    }
                    printf("
    ");
                    flag=0;
                }
                else if(p==dp->pt->ptr[0]){
                    while(dp->pt!=p){
                        BTree tmp=dp->pt;
                        for(i=0;i<=tmp->keynum;i++){
                            printf("[ ");
                            for(j=1;j<=tmp->ptr[i]->keynum;j++){
                                printf("%d ",tmp->ptr[i]->key[j]);
                            }
                            printf("] ");
                        }
                        dp=dp->next;
                    }
                    printf("
    ");
                }
                for(i=0;i<=p->keynum;i++){
                    if(p->ptr[i]){
                        ap=(queueBTree)malloc(sizeof(queueBNT));
                        ap->pt=p->ptr[i]; ap->next=NULL;
    
                        pr->next=ap; pr=ap;
                    }
                }
                pl=pl->next;
            }
            while(root!=NULL){
                q=root;
                root=root->next;
                free(q);
            }
        }
    }
    void printarray(int k,BTree t)
    {
        int array1[k];
        if(t==NULL)
            {
            printf("
    ");
            printf("arrary is empty.");
            printf("
    ");
        }
        else {
            int i,j,k2=0,kk=0,temp=0;
            BTree p;
            queueBTree root,pl,pr,ap,q,dp;
            pl=(queueBTree)malloc(sizeof(queueBNT));
            root=pl;
            pl->pt=t; pl->next=NULL; pr=pl;
            p=pl->pt;
            for(i=1;i<=t->keynum;i++){
                array1[k2]=p->key[i];
                k2++;
            }
            dp=pl;
            int flag=1;
            while(pl){
                p=pl->pt;
                if(flag&&p->ptr[0]==NULL&&p!=t){
                    while(dp!=NULL&&dp->pt!=p){
                        BTree tmp=dp->pt;
                        for(i=0;i<=tmp->keynum;i++){
                            for(j=1;j<=tmp->ptr[i]->keynum;j++){
                                array1[k2]=tmp->ptr[i]->key[j];
                                k2++;
                            }
                        }
                        dp=dp->next;
                    }
                    printf("
    ");
                    flag=0;
                }
                else if(p==dp->pt->ptr[0]){
                    while(dp->pt!=p){
                        BTree tmp=dp->pt;
                        for(i=0;i<=tmp->keynum;i++){
                            for(j=1;j<=tmp->ptr[i]->keynum;j++){
                            array1[k2]=tmp->ptr[i]->key[j];
                            k2++;
                            }
                        }
                        dp=dp->next;
                    }
                }
                for(i=0;i<=p->keynum;i++){
                    if(p->ptr[i]){
                        ap=(queueBTree)malloc(sizeof(queueBNT));
                        ap->pt=p->ptr[i]; ap->next=NULL;
                        pr->next=ap; pr=ap;
                    }
                }
                pl=pl->next;
            }
            while(root!=NULL)
                {
                q=root;
                root=root->next;
                free(q);
            }
            for(i=0;i<k;i++)
                {
    	 	//每趟从第一个数开始排,第一趟排完将最大的一个数沉底(即放在数组最后一个位置),
                    for(j=0;j<k-i;j++)
                    {
    			//前面一个数比后面一个数大时,交换他俩的位置
                        if(array1[j]>array1[j+1])
                        {
                        kk=array1[j];
                        array1[j]=array1[j+1];
                        array1[j+1]=kk;
                        }
                        for(int a=0;a<k;a++)//冒泡排序
                        {
                            for(int b=a+1;b<k;b++)
                            {
                                if(array1[a]>array1[b])
                                {
                                    temp = array1[a];
                                    array1[a] = array1[b];
                                    array1[b] = temp;
                                }
                            }
                        }
    
                        for(i=0;i<k;i++)
                        {
                            printf("%d	",array1[i]);
                        }
                    }
                }
        }
    }
    void Test(){
        //system("color 4F");
        BTree t=NULL;
        int n,key,flag;
        result r;
        int k=0;
        while(1) {
            printf("
    ");
            printBTree(t);
            printf("
    ");
            printf("|--------------------------------------------|
    ");
            printf("|  1 B树置空     2 插入关键字  3 查询关键字  |
    ");
            printf("|  4 删除关键字  5 输出B树     6 销毁B树     |
    ");
            printf("|        7升序输出B树       0 退出           |
    ");
            printf("|--------------------------------------------|
    ");
    
            printf("Enter number to choose operation:_____");
            scanf("%d",&n);
            switch(n){
                case 1:{
                    init(t);
                    printf("
    ");
                    printf("InitBTree successfully.
    ");
                    printf("
    ");
                    break;
                }
                case 2:{
                    printf("Enter number to InsertBTree:_____");
                    scanf("%d",&key);
                    insertBTree(t,key);
                    printf("
    ");
                    printf("Insert  %d   successfully.
    ",key);
                    printf("
    ");
                    k++;
                    break;
                }
                case 3:{
                    printf("Enter number to searchBTree:_____");
                    scanf("%d",&key);
                    searchBTree(t,key,r);
                    printf("
    ");
                    if(r.tag==1)printf("the keyelement  %d  succeed found.
    ",key);
                    else printf("failed to find the keyelement  %d   
    ",key);
                    printf("
    ");
                    break;
                }
                case 4:{
                    printf("Enter number to DeleteBTree:_____");
                    scanf("%d",&key);
                    flag = deleteBTree(t,key);
                    printf("
    ");
                    if(flag==0)printf("the keyelement   %d  isn`t existed.
    ",key);
                    else printf("Delete the keyelement  %d  successfully.
    ",key);
                    printf("
    ");
                    break;
                }
                case 5:{
                    printf("
    ");
                    printBTree(t);
                    printf("
    ");
                    break;
                }
                case 6:{
                    DestoryBTree(t);
                    printf("
    ");
                    printf("BTree is destoryed successfully");
                    printf("
    ");
                    break;
                }
                case 7:{
                    printf("
    ");
                    printarray(k,t);
                    printf("
    ");
                    break;
                }
                case 0:{
                    exit(-1);
                    break;
                }
                default:{
                    printf("
    ");
                    printf("invalid operation.
    ");
                    printf("
    ");
                }
            }
        }
    }
    
    int main()
    {
        Test();
        return 0;
    }
    


  • 相关阅读:
    nginx不支持pathinfo模式解决方法
    php只保留两位小数
    分享图文到QQ空间
    android 使用信鸽推送通知栏不显示推送的通知?
    Editetext获取焦点后让输入软键盘中出现搜索按键
    Android EditText的使用过程中遇到的问题
    在线根据现有apk生成指定id的推广apk (已过时)
    @Validated和@Valid区别
    idea快捷键使用总结
    大概
  • 原文地址:https://www.cnblogs.com/liang-xp/p/14793749.html
Copyright © 2011-2022 走看看