块状链表及其实现
来源:互联网 发布:unity3d教程百度云 编辑:程序博客网 时间:2024/06/07 09:34
数组和链表是编程中存储数据的常用方法,两者都用优缺点,数组根据下标直接访问元素,但数组是静态的,有时会造成空间的浪费;链表可以动态申请空间,但访问需要进行遍历。于是乎,块状链表就出来了。
块状链表的结构如下图:
每个节点存储m个数据。节点的定义如下:
struct data{int s,a[2*m+5];data *next;};data *root;
next指向下一个节点,s是该节点的存储的实际数据的大小,a是存储数据的数组。
块状链表支持数据的插入、删除、查询等操作。
(1)插入(insert):数据插入的时候,插入的位置(pos)必须是合法的,也就是说不能大于数据的总数(n)。
数据插入过程:首先找到Pos位于哪个节点中,先将该节点pos及pos后面的数据(如果存在的话)向后移一位,然后将值x插入,将s加1。每个节点的存储的数据上限为2*n,如果达到这个上限,这需要在该节点后面新加一个节点,将m+1到2*m的数据复制到新建的节点。
void insert(int x,int pos){if(root == NULL){root = new(data);root->s = 1;root->a[1] = x;return ;}data *k = root;while(pos > k->s && k->next != NULL){pos -= k->s;k = k->next;}memmove(k->a+pos+1,k->a+pos,sizeof(int)*(k->s - pos +1));k->s++;k->a[pos] = x;if(k->s == 2*m){data *t = new(data);t->next = k->next;k->next = t;memcpy(t->a+1,k->a+m+1,sizeof(int)*m);t->s = k->s = m;}}
(2)删除(delete):插入和删除类似,首先找到pos所在的节点,把Pos后面的数据向前移动一位,然后该节点的s-1。
void del(int pos){data *k = root;while(pos > k->s && k->next != NULL){pos -= k->s;k = k->next;}memmove(k->a+pos,k->a+pos+1,sizeof(int)*(k->s - pos));k->s--;}
(3)查找(find):查找位置为Pos的数,找到pos所在节点,返回该值即可。
int find(int pos){data *k = root;while(pos > k->s && k->next != NULL){pos -= k->s;k = k->next;}return k->a[pos];}
(此段from:点击打开链接)(董的博客)
关键点和复杂度分析
该算法的核心是确定链表长度和每个节点的数组长度,以及怎么保证这个长度值?设块状链表中元素总个数为X,链表长度为n,每个节点中数据长度为m,则当m=n=sqrt(X)时,可保证m和n同时最小,此时各种操作的时间复杂度最低。在实际应用时,需维持块状链表的每个节点大小在[sqrt(n)/2, 2*sqrt(n)],否则,块状链表会退化。维护方法是,适当的时候,对节点进行合并与分裂(维护本身不会使复杂度增加)。
0 0
- 块状链表及其实现
- 块状链表基本操作及其相关例题
- 块状链表
- 块状链表 poj2887
- 块状链表
- 数据结构:块状链表
- 数据结构:块状链表
- java 块状链表
- 块状链表
- 块状链表
- 块状链表
- *块状链表
- POJ2887【块状链表】
- 块状链表模板
- 模板:块状链表
- 初识块状数组/块状链表(讲解+ 例题)
- 数据结构之块状链表
- ZOJ 2112 块状链表
- 用ctags在终端下查看代码
- Linux设备驱动--LCD平台设备与驱动(smdk2440)
- 合并果子
- CNN卷积神经网络--反向传播(4,代码理解)
- Solr文档学习--Using the Solr Administration User Interface
- 块状链表及其实现
- ios中用到的数学函数
- 设计模式之观察者模式
- ACID
- String类型转成bigdecimal类型
- 【基础学习】Android可伸缩文本内容显示
- Oracle 12c RAC: Clusterware logs are now centralized
- HTTP请求方法
- Android_ContentProvider详解(实现增删改查)