块状链表

我去,太难写了……

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

有着非常优秀的性质

查询和删除都是\(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 稳定块状链表

……未完待续

posted @ 2017-12-24 10:30  Grary  阅读(1012)  评论(0编辑  收藏  举报
博客园 首页 私信博主 编辑 关注 管理 新世界