zoukankan      html  css  js  c++  java
  • 块状链表

    我去,太难写了……

    块状链表作为一种集成了链表和分块的数据结构,

    有着非常优秀的性质

    查询和删除都是(O(sqrt{n} ))复杂度的



    需要支持的操作

    1.创建一个新节点

    2.插入一个新节点

    3.删除一个旧节点

    4.向已知节点中加入新值

    5.删除已知节点中某些值

    6.合并某两个相邻的节点

    7.把一个节点分离成两个




    那么需要的成员函数有

    1.建立新块(new Block 函数)

    2.建立新节点 (new node 函数)

    3.初始化节点 (block list 函数)

    4.在节点前插入一个点(Insert a Node 函数)

    5.在节点后插入一个点(Insert a Node 函数)

    6.将一段数据插入到链表(即为 build 函数)

    7.将一个节点删除(Delete 函数)

    8.将一个节点的某一段删除(Delete 函数)

    9.将一段区间删除(Delete 函数)

    10.合并两个节点 (merge 函数)

    11.分离一个节点(split 函数)

    12.智能维护块状链表稳定的函数 (balance 函数)





    我们同样需要一个"缓存区"

    用于存储初始数据和交换数据

    这其中某些操作可以通过其他几种操作组合得来

    例如分离两个节点可以删除这个节点,

    这个代码好难写……233333


    ## 为了保证链表结构的基本稳定, 我们需要一个自动合并和分离以达到控制每一块大小目的的函数

    还需要一个数据结构来存放块的大小,并且支持查询大小在这个范围内的块

    那么这个这个块状链表就能实现动态的稳定,而不会退化成数组或者是链表

    这个维护链表稳定的结构可以用Vector来实现

    Code 1.1.2 基本框架(分块,建表,遍历)

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #define N 5555
    using namespace std;
    
    int data[N*N];
    
    struct Block{
        int s[N],len;
        void print(){
            cout<<"[";
            for(int i=0;i<len;++i)
                cout<<s[i]<<"->";
            cout<<"]";
            cout<<"  "<<len;
            cout<<endl;
        }
    };
    
    class BlockList{
        struct Node{
            Node* nxt;
            Node* pre;
            Block data;
        };
        Node* head;
        Node* tail;
        int len;
        Block newBlock(int l,int r){
            Block now;now.len=r-l+1;
            for(int i=l;i<=r;++i){
                now.s[i-l]=data[i];
            }
            return now;
        }
        Node* newnode(int l,int r){
            Node* now=(Node*)malloc(sizeof(Node));
            now->nxt=now->pre=NULL;
            now->data=newBlock(l,r);
            return now;
        }
        bool InsertANode(Node* root,int l,int r){
            if(root==tail)return false;
            if(root==NULL)return false;
            Node* in=newnode(l,r);
            Node* tmp=root->nxt;
            in->nxt=tmp;in->pre=root;
            root->nxt=in;tmp->pre=in;
            len++;
            return true;
        }
        bool InsertANode(int l,int r,Node* root){
            if(root==head)return false;
            if(root==NULL)return false;
            Node* in=newnode(l,r);
            Node* tmp=root->pre;
            in->pre=tmp;in->nxt=root;
            root->pre=in;tmp->nxt=in;
            len++;
            return true;
        }
        public:
        BlockList(){
            head=newnode(0,-1);
            tail=newnode(0,-1);
            head->nxt=tail;tail->pre=head;
        }
        bool build(int n){
            int bs=sqrt(n);
            int b=bs+1;
            for(int i=1;i<=b;++i){
                InsertANode((i-1)*bs+1,i*bs>n?n:i*bs,tail);
            }
            return true;
        }
        void print(){
            Node* now=head;
            while(now!=NULL){
                now->data.print();
                now=now->nxt;
            }
        }
    }f;
    
    int main(){
        int n;
        cin>>n;
        for(int i=1;i<=n;++i)
            cin>>data[i];
        f.build(n);
        f.print();
        cout<<endl;
        return 0;
    }
    

    Code 1.2 基本序列操作 1 (删除任意区间元素)

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #define N 5555
    using namespace std;
    
    int data[N*N];
    
    struct Block{
        int s[N],len;
        void print(){
            cout<<"[";
            for(int i=0;i<len;++i)
                cout<<s[i]<<"->";
            cout<<"]";
            cout<<"  "<<len;
            cout<<endl;
        }
    };
    
    class BlockList{
        public:
        struct Node{
            Node* nxt;
            Node* pre;
            Block data;
        };
        Node* head;
        Node* tail;
        int len;
        Block newBlock(int l,int r){
            Block now;now.len=r-l+1;
            for(int i=l;i<=r;++i){
                now.s[i-l]=data[i];
            }
            return now;
        }
        Node* newnode(int l,int r){
            Node* now=(Node*)malloc(sizeof(Node));
            now->nxt=now->pre=NULL;
            now->data=newBlock(l,r);
            return now;
        }
        BlockList(){
            head=newnode(0,-1);
            tail=newnode(0,-1);
            head->nxt=tail;tail->pre=head;
        }
        bool InsertANode(Node* root,int l,int r){
            if(root==tail)return false;
            if(root==NULL)return false;
            Node* in=newnode(l,r);
            Node* tmp=root->nxt;
            in->nxt=tmp;in->pre=root;
            root->nxt=in;tmp->pre=in;
            len++;
            return true;
        }
        bool InsertANode(int l,int r,Node* root){
            if(root==head)return false;
            if(root==NULL)return false;
            Node* in=newnode(l,r);
            Node* tmp=root->pre;
            in->pre=tmp;in->nxt=root;
            root->pre=in;tmp->nxt=in;
            len++;
            return true;
        }
        bool build(int n){
            int bs=sqrt(n);
            int b=bs+1;
            for(int i=1;i<=b;++i){
                InsertANode((i-1)*bs+1,i*bs>n?n:i*bs,tail);
            }
            return true;
        }
        void print(){
            Node* now=head;
            while(now!=NULL){
                now->data.print();
                now=now->nxt;
            }
        }
        bool Delete(Node* root){
            if(root==head)return false;
            if(root==tail)return false;
            root->pre->nxt=root->nxt;
            root->nxt->pre=root->pre;
            return true;
        }
        void Delete(Node* root,int l,int r){
            cout<<r<<' '<<l<<endl;
            int R=r-l+1;
            int sum=-1;
            for(int i=r+1;i<len;++i)
                data[++sum]=root->data.s[i];
            int begin=0;
            for(int i=l;i<len&&begin<=sum;++i)
                root->data.s[i]=data[begin++];
            root->data.len-=R;
        }
        bool Delete(int l,int r){
            Node* now=head->nxt;
            int L=1,R=0;
            while(r>R){
                if(now==NULL)
                    return false;
                int length=now->data.len,flag=true;
                R+=length;
                if(L>=l&&R<=r){
                    Delete(now);
                    flag=false;
                }
                else if(L>=l&&R>=r)
                    Delete(now,0,r-L);
                else if(L<=l&&R<=r)
                    Delete(now,l-L,now->data.len-1);
                L+=length;
                now=now->nxt;
            }
            return true;
        }
    }f;
    
    int main(){
        int n;
        cin>>n;
        for(int i=1;i<=n;++i)
            cin>>data[i];
        f.build(n);
        for(int i=1;i<=1;++i)
            f.Delete(2,8);
        f.print();
        cout<<endl;
        return 0;
    }
    

    Code 1.3 基本序列操作(任意增加元素)

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #define N 5555
    using namespace std;
    
    int data[N*N];
    
    struct Block{
        int s[N],len;
        void print(){
            cout<<"[";
            for(int i=0;i<len;++i)
                cout<<s[i]<<"->";
            cout<<"]";
            cout<<"  "<<len;
            cout<<endl;
        }
    };
    
    class BlockList{
        public:
        struct Node{
            Node* nxt;
            Node* pre;
            Block data;
        };
        Node* head;
        Node* tail;
        int len,block;
        Block newBlock(int l,int r){
            Block now;now.len=r-l+1;
            for(int i=l;i<=r;++i){
                now.s[i-l]=data[i];
            }
            return now;
        }
        Node* newnode(int l,int r){
            Node* now=(Node*)malloc(sizeof(Node));
            now->nxt=now->pre=NULL;
            now->data=newBlock(l,r);
            return now;
        }
        BlockList(){
            head=newnode(0,-1);
            tail=newnode(0,-1);
            head->nxt=tail;tail->pre=head;
        }
        bool InsertANode(Node* root,int l,int r){
            if(root==tail)return false;
            if(root==NULL)return false;
            Node* in=newnode(l,r);
            Node* tmp=root->nxt;
            in->nxt=tmp;in->pre=root;
            root->nxt=in;tmp->pre=in;
            len++;
            return true;
        }
        bool InsertANode(int l,int r,Node* root){
            if(root==head)return false;
            if(root==NULL)return false;
            Node* in=newnode(l,r);
            Node* tmp=root->pre;
            in->pre=tmp;in->nxt=root;
            root->pre=in;tmp->nxt=in;
            len++;
            return true;
        }
        bool build(int n){
            int bs=sqrt(n);
            int b=bs+1;
            for(int i=1;i<=b;++i){
                InsertANode((i-1)*bs+1,i*bs>n?n:i*bs,tail);
            }
            block=bs;
            return true;
        }
        bool add(Node* root,int n){
            int kuai=n/block+1;
            for(int i=1;i<=kuai;++i){
                InsertANode(root,(i-1)*block+1,i*block>n?n:i*block);
                root=root->nxt;
            }
        }
        void print(){
            Node* now=head;
            while(now!=NULL){
                now->data.print();
                now=now->nxt;
            }
        }
        bool Delete(Node* root){
            if(root==head)return false;
            if(root==tail)return false;
            root->pre->nxt=root->nxt;
            root->nxt->pre=root->pre;
            return true;
        }
        void Delete(Node* root,int l,int r){
            cout<<r<<' '<<l<<endl;
            int R=r-l+1;
            int sum=-1;
            for(int i=r+1;i<len;++i)
                data[++sum]=root->data.s[i];
            int begin=0;
            for(int i=l;i<len&&begin<=sum;++i)
                root->data.s[i]=data[begin++];
            root->data.len-=R;
        }
        bool Delete(int l,int r){
            Node* now=head->nxt;
            int L=1,R=0;
            while(r>R){
                if(now==NULL)
                    return false;
                int length=now->data.len,flag=true;
                R+=length;
                if(L>=l&&R<=r){
                    Delete(now);
                    flag=false;
                }
                else if(L>=l&&R>=r)
                    Delete(now,0,r-L);
                else if(L<=l&&R<=r)
                    Delete(now,l-L,now->data.len-1);
                L+=length;
                now=now->nxt;
            }
            return true;
        }
    }f;
    
    int main(){
        int n;
        cin>>n;
        for(int i=1;i<=n;++i)
            cin>>data[i];
        f.build(n);
        int m;
        cin>>m;
        for(int i=1;i<=m;++i)
            cin>>data[i];
        f.add(f.head,m);
        f.print();
        cout<<endl;
        return 0;
    }
    




    接下来的balance 函数就不是那么好写了
    需要对整个程序进行大换血

    Code 1.3 稳定块状链表

    ……未完待续

  • 相关阅读:
    招聘asp.net mvc, C#软件开发
    成功后面是付出===来硅谷三个月来第一篇关于硅谷的文章
    招聘Web前端开发
    记人之长,忘人之短;谈人之善,容人之过
    如何减少Outlook占用空间
    流程管理误区
    在Windows Server 2008上安装 Windows SharePoint Services 3.0
    在WinXP or Vista上开发Webpart
    成功后面是付出===来硅谷三个月来第一篇关于硅谷的文章(续篇)
    poj 2362 hdoj 1518 Square(搜索)
  • 原文地址:https://www.cnblogs.com/qdscwyy/p/8097489.html
Copyright © 2011-2022 走看看