诸如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. 【BZOJ 2039】 2039: [2009国家集训队]employ人员雇佣 (最小割)

    2039: [2009国家集训队]employ人员雇佣 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1511  Solved: 728 Descri ...

  2. 较有意思的Apple XSS(CVE-2016-7762)漏洞

    文章作者:Avfisher0x00 前言应CVE作者的要求帮忙分析一下这个漏洞,实际上这是一个思路比较有意思的Apple XSS(CVE-2016-7762).漏洞作者确实脑洞比较大也善于尝试和发掘, ...

  3. EMGU 2.9.X在VS2010下调试真正靠谱的配置

    emgu有多强大或者干什么的网上找资料吧.这里就说说我在2010下的配置的经历. 在网上找了很多资料,有细节到一步一步的,但我跟着弄还是没有成功.比如修改cpu,复制emgu的bin目录下某些所需文件 ...

  4. Java类实例化原理

    Java对象的创建过程包括 类初始化(JVM类加载机制)和类实例化两个阶段. 一.Java对象创建时机 (1)使用new关键字创建对象 (2)反射创建对象 使用Class类的newInstance方法 ...

  5. 2349 Arctic Network(中文版)

    试题描述: 国防部希望通过无线网络连接几个北方前哨基地. 在建立网络时将使用两种不同的通信技术:每个前哨基站都将拥有无线电收发器,另外还有一些前哨卫星通道. 任何带卫星频道的两个前哨都可以通过卫星进行 ...

  6. Educational Codeforces Round 12 C. Simple Strings 贪心

    C. Simple Strings 题目连接: http://www.codeforces.com/contest/665/problem/C Description zscoder loves si ...

  7. SQl CASE 语句的嵌套使用方式

    case具有两种格式.简单case函数和case搜索函数.  1.简单case函数 case sex when ’1’ then ’男’ when ’2’ then ’女’else ’其他’ end ...

  8. IPtables/NetFilter

    前提知识 任何主机若要与非同网络中的主机通信,则必须将报文发送到默认网关: 对Linux而言,IP地址是属于主机(内核中)的,不属于网卡,只要属于当前主机的IP地址间,都可直接响应,不称为转发 私有地 ...

  9. [ext]form.submit()相关说明

    form.submit({    url:"../addOrUpdatePack.shtml",method:'POST',success:function(f,action) { ...

  10. mysql数据库测试库下载

    The mysqlslap program can be helpful for simulating a high load produced by multiple clients issuing ...