诸如BASIC和FORTRAN等许多语言都不支持指针。如果需要链表而又不能使用指针,这时我们可以使用游标(cursor)实现法来实现链表。

在链表的实现中有两个重要的特点:

数据存储在一组结构体中。每一个结构体包含有数据以及指向下一个结构体的指针。

一个新的结构体可以通过调用malloc而从系统全局内存(global memory)得到,并可以通过free而被释放。

游标法必须能够模仿实现这两条特性:

定义一个全局的结构体数组(模拟系统全局内存)。对于数组中的任何单元,其数组下标可以用来代表一个地址。

typedef int ptr_to_node;
typedef ptr_to_node list;
typedef ptr_to_node position; struct node
{
element_type element;
position next;
}; struct node cursor_space[spacesize];

在这个全局的结构体数组中,保留一个表freelist作为备用单链表,用来malloc或free游标可用空间,该表用0作为表头。刚开始时,freelist就是整个结构体数组。

需要理解的是:所有的链表,包括备用表和已用表,全部都在我们定义的全局结构体数组中,只是它们的表头不同,从不同的表头出发形成了不同的单链表。

假设我们定义了一个大小为11的游标空间,其初始化状态如下:

Slot Element Next
0

1

2

3

4

5

6

7

8

9

10

  1

2

3

4

5

6

7

8

9

10

0

注:对于Next, 0的值等价于NULL指针。

上面的状态用链表形式表示为:cursor_space[0]—>cursor_space[1]—>cursor_space[2]—>cursor_space[3]—>cursor_space[4]—>cursor_space[5]—>cursor_space[6]—>cursor_space[7]—>cursor_space[8]—>cursor_space[9]—>cursor_space[10]—>NULL.

为执行malloc功能,将(在表头后面的)第一个元素从freelist中删除。为了执行free功能,我们将该单元放在freelist的前端。

malloc和free的游标实现如下:

static position
cursor_alloc(void)
{
position p; p = cursor_space[0].next;
cursor_space[0].next = cursor_space[p].next; return p;
} static void
cursor_free(position p)
{
cursor_space[p].next = cursor_space[0].next;
cursor_space[0].next = p;
}

为加深理解,请参考如下实例:

Slot Element Next
0

1

2

3

4

5

6

7

8

9

10

-

b

f

header

-

header

-

c

d

e

a

6

9

0

7

0

10

4

8

2

0

1

如果单链表L的值是5,M的值是3,我们又规定了freelist表头为0,因此,从上表中我们可以得到三个链表:

freelist:cursor_space[0]—>cursor_space[6]—>cursor_space[4]—>NULL 

L:header—>a—>b—>e—>NULL

M:header—>c—>d—>f—>NULL

freelist是分配L、M链表后还剩余的可分配空间。

 

游标实现

/* return ture if L is empty */
int isempty(list L)
{
return cursor_space[L].next = 0;
}
/* return true if P is the last position in list L */

int islast(position p, list L)
{
return cursor_space[P].next == 0;
}
/* return position of X in L; 0 if not found */
/* uses a header node */ position find(element_type X, list L)
{
position p; p = cursor_space[L].next;
while(p && cursor_space[p].element != X)
p = cursor_space[p].next; return p;
}
/* delete first occurence of X from a list */
/* assume use of a header node */ void delete(element_type X, list L)
{
position p, tmpcell; p = find_previous(X, L); if(!islast(p, L))
{
tmpcell = cursor_space[p].next;
cursor_space[p].next = cursor_space[tmpcell].next;
cursor_free(tmpcell);
}
}
/* insert (after legal position P) */

void insert(element_type X, list L, position P)
{
position tmpcell; tmpcell = cursor_alloc();
if(tmpcell == 0)
fatal_error("out of sapce!!!"); cursor_space[tmpcell].element = X;
cursor_space[tmpcell].next = cursor_space[P].next;
cursor_space[P].next = tmpcell;
}

链表的游标(cursor)实现的更多相关文章

  1. SQL Server 数据库的维护(四)__游标(cursor)

    --维护数据库-- --游标(cursor)-- --概述: 注:使用select语句查询结果的结果集是一个整体,如果想每次处理一行或一部分行数据,游标可以提供这种处理机制.可以将游标理解为指针.指针 ...

  2. 分组PARTITION BY及游标CURSOR的用法

    基础数据表: select * from dbo.RecommendationChanelVersionRelation: 数据如下: 要求按照ChannelVersionID分组,对每组中的Orde ...

  3. MySQL游标(cursor) 定义及使用

    概念 游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集. 使用游标(cursor)的一个主要的原因就是把集合操作转换成单个记录处理方式. 用SQL语言从数据库中检索数据后,结果 ...

  4. ORACLE中的游标Cursor总结

    游标(Cursor):用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作. 游标可分为: 1.       静态游标:分为显式(explicit)游标和 ...

  5. PL/SQL使用游标CURSOR

    一.使用游标 对于DML语句和单行select into ,oracle自动分配隐形游标.处理select返回多行语句,可以使用显式游标. 使用显示游标处理多行数据,也可使用SELECT..BULK ...

  6. 游标cursor

    if exists(select * from sys.objects where name='info_one') drop table info_one go create table info_ ...

  7. SQL游标(cursor)详细说明及内部循环使用示例

    游标 游标(cursor)是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果.每个游标区都有一个名字,用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理. 游标是处理 ...

  8. SQLServer游标(Cursor) (B)

    游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次以行或者多行前进或向后浏览数据的能力.我们可以把游标当作一个指针,它可以指定结果中的任何位置,然后允许 ...

  9. MySql使用游标Cursor循环(While)更新数据

    #要修改的变量 DECLARE var_ID VARCHAR(50) DEFAULT ''; #需要修改的数据的数量 DECLARE var_UpdateCount INT; #当前循环次数 DECL ...

随机推荐

  1. android 启动流程

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha adb shell 后  用 ps 命令 回车 可以看到 运行的进程. 如下结果: ct ...

  2. [BZOJ4873][六省联考2017]寿司餐厅(最大权闭合子图)

    4873: [Shoi2017]寿司餐厅 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 490  Solved: 350[Submit][Status ...

  3. HDU 6084 寻找母串(卡特兰数)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6084 [题目大意] 对于一个串S,当它同时满足如下条件时,它就是一个01偏串: 1.只由0和1两种 ...

  4. 什么是ClassLoader

    ClassLoader 做什么的? 顾名思义,它是用来加载 Class 的.它负责将 Class 的字节码形式转换成内存形式的 Class 对象.字节码可以来自于磁盘文件 *.class,也可以是 j ...

  5. bzoj 3585: mex && 3339: Rmq Problem -- 主席树

    3585: mex Time Limit: 20 Sec  Memory Limit: 128 MB Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区 ...

  6. 某DP题目2

    题意: 有一个栈,有n个数1~n按顺序插进栈中,但弹出顺序不定.另有m个限制,表示为a b,即数a必须在数b弹出之前弹出.问有多少种弹出的方案数.n <= 300,m <= 90000 分 ...

  7. Codeforces Beta Round #7 A. Kalevitch and Chess 水题

    A. Kalevitch and Chess 题目连接: http://www.codeforces.com/contest/7/problem/A Description A famous Berl ...

  8. Unity Pivot/Center与Local/Global总结

    Untiy左上角有两个按钮  Pivot/Center 和 Local/Global  它们叫做 变换Gizmo工具 Pivot/Center:现实游戏对象的轴心参考点.Center为以所有选中物体所 ...

  9. POJ 1222 POJ 1830 POJ 1681 POJ 1753 POJ 3185 高斯消元求解一类开关问题

    http://poj.org/problem?id=1222 http://poj.org/problem?id=1830 http://poj.org/problem?id=1681 http:// ...

  10. XuLA/XuLA2

    http://www.xess.com/prods/prod048.php XuLA http://www.xess.com/prods/prod055.php XuLA2 http://www.xe ...