块状链表

/*
* 本模板支持以下操作:
* 1.在任意位置插入一个整数
* 2.插入一个块(Block),包含多个整数
* 3.删除一个整数
* 4.输出第i位上的整数
* 注意:所有Insert(pos,data),均是在pos之后插入。
* BlockList::N是sqrt(n)的结果,它决定了块状链表的效率
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#define MAXSIZE 1000
namespace BlockList{
    int N;
    class Block{
    public:
        int size;
        Block* next;
        int data[MAXSIZE+2];
        inline Block(){
            size=0;
        }
        inline int& select(int x){
            return data[x];
        }
        void Insert(int pos,int x);
        void Delete(int pos);
    };
    inline void Block::Insert(int pos,int x){
        this->size++;
        for (int i=size;i>pos+1;–i){
            data[i]=data[i-1];
        }
        data[pos+1]=x;
    }
    inline void Block::Delete(int pos){
        for (int i=pos;i<size;++i){
            data[i]=data[i+1];
        }
        size–;
    }
    class List{
    public:
        Block* Head;
        int size;
        inline List(){
            size=0;
        }
        void Insert(const int,const Block*);
        void Insert(const int,const int );
        void Delete(int pos);
        inline int get(int pos);
    };
    inline int List::get(int pos){
        int sum=0;
        if (pos>size) return -1;
        for (Block* p=Head;p;p=p->next){
            if (sum+p->size>=pos){
                return p->data[pos-sum];
            }
        }
    }
    inline void Div(Block *data,const int pos){
        if (pos<=data->size) return ;
        Block *p1=new Block,*p2=new Block;
        p1->size=pos;
        for (int i=1;i<=pos;++i){
            p1->data[i]=data->data[i];
        }
        p2->size=data->size-pos;
        for (int i=1;i<=p2->size;++i){
            p2->data[i]=data->data[i+pos];
        }
        p1->next=p2;
        p2->next=data;
        delete data;
        data=p1;
    }
    inline void Union(Block *a,Block * b){
        Block* p=new Block;
        p->size=a->size+b->size;
        for (int i=1;i<=a->size;++i){
            p->data[i]=a->data[i];
        }
        for (int i=1;i<=b->size;++i){
            p->data[i+a->size]=b->data[i];
        }
        p->next=b->next;
        delete a;
        delete b;
        a=p;
    }
    void List::Insert(const int pos,const Block* x)
    {
        int sum=0;
        if (!Head)
        {
            Block* p=new Block;
            memcpy(p,x,sizeof(p));
            size=x->size;
            Head=p;
            return ;
        }
        if (pos<Head->size){
            Div(Head,pos);
            Block* next=Head->next;
            Block* p=new Block;
            memcpy(p,x,sizeof(p));
            Head->next=p;
            p->next=next;
            if (Head->size+p->size<N) Union(Head,p);
            else if (p->size+next->size<N) Union(p,next);
                return;
        }
        sum+=Head->size;
        Block* pre=Head;
        for (Block *p=Head->next;p;p=p->next)
        {
            sum+=p->size;
            if (sum==pos){
                Block *tmp=new Block;
                memcpy(tmp,x,sizeof(tmp));
                pre->next=tmp;
                tmp->next=p;
                
                if (pre->size+tmp->size<N){
                    Union(pre,tmp);
                }else if (tmp->size+p->size<N){
                    Union(tmp,p);
                }
                return ;
            }
            if (sum>pos){
                Block *tmp=new Block;
                memcpy(tmp,x,sizeof(tmp));
                Block *obj=p;
                Div(p,pos-(sum-p->size));
                Block *next=obj->next;
                obj->next=tmp;
                tmp->next=next;
                if (pre->size+tmp->size<N){
                    Union(obj,tmp);
                }else if (tmp->size+p->size<N){
                    Union(tmp,next);
                }
                return ;
            }
            pre=p;
        }
    }
    void List::Insert(const int pos,const int x)
    {
        int sum=0;
        size++;
        if (!Head)
        {
            Block* p=new Block;
            p->size=1;
            p->data[1]=x;
            Head=p;
            return ;
        }
        if (pos<=Head->size){
            Head->Insert(pos,x);
            return;
        }
        sum+=Head->size;
        Block* pre=Head;
        for (Block *p=Head->next;p;p=p->next)
        {
            sum+=p->size;
            if (sum>=pos){
                p->Insert(pos-(sum-p->size),x);
                return ;
            }
        }
    }
    inline void List::Delete(int pos){
        int sum=0;
        if (pos>size )return;
        size–;
        for (Block *p=Head;p;p=p->next){
            if (sum+p->size>=pos){
                p->Delete(pos-sum);
                return ;
            }
        }
    }
}
BlockList::List d;
int main(){
    BlockList::N=500;
    int op,tmp1,tmp2;
    while (~scanf("%d",&op)){
        if (op==1){
            scanf("%d%d",&tmp1,&tmp2);
            d.Insert(tmp1,tmp2);
        }
        if (op==2){
            scanf("%d",&tmp1);
            d.Delete(tmp1);
        }
        if (op==3){
            scanf("%d",&tmp1);
            printf("%dn",d.get(tmp1));
        }
    }
}


转载自  http://sweetdum.com/wordpress/?p=172

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值