块状链表
我去,太难写了……
块状链表作为一种集成了链表和分块的数据结构,
有着非常优秀的性质
查询和删除都是\(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 稳定块状链表
……未完待续
为什么要过别人为我安排的生活.